Travis CI Π΅ ΡΠ°Π·ΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π° ΡΠ΅Π± ΡΡΠ»ΡΠ³Π° Π·Π° ΠΈΠ·Π³ΡΠ°ΠΆΠ΄Π°Π½Π΅ ΠΈ ΡΠ΅ΡΡΠ²Π°Π½Π΅ Π½Π° ΡΠΎΡΡΡΠ΅Ρ, ΠΊΠΎΠΉΡΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° GitHub ΠΊΠ°ΡΠΎ Ρ
ΠΎΡΡΠΈΠ½Π³ Π½Π° ΠΈΠ·Ρ
ΠΎΠ΄Π½ΠΈΡ ΠΊΠΎΠ΄. Π Π΄ΠΎΠΏΡΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊΡΠΌ Π³ΠΎΡΠ½ΠΈΡΠ΅ ΡΠ°Π±ΠΎΡΠ½ΠΈ ΡΡΠ΅Π½Π°ΡΠΈΠΈ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΡΠ΅ ΡΠ²ΠΎΠΈ ΡΠΎΠ±ΡΡΠ²Π΅Π½ΠΈ Π±Π»Π°Π³ΠΎΠ΄Π°ΡΠ΅Π½ΠΈΠ΅ Π½Π° ΠΎΠ±ΡΠΈΡΠ½ΠΈΡΠ΅ ΠΎΠΏΡΠΈΠΈ Π·Π° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠΈΡΠ°Π½Π΅. Π ΡΠ°Π·ΠΈ ΡΡΠ°ΡΠΈΡ ΡΠ΅ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠΈΡΠ°ΠΌΠ΅ Travis CI Π΄Π° ΡΠ°Π±ΠΎΡΠΈ Ρ PVS-Studio, ΠΊΠ°ΡΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠΏΡΠΈΠΌΠ΅ΡΠ½ΠΈΡ ΠΊΠΎΠ΄ Π½Π° PPSSPP.
Π²ΡΠ²Π΅Π΄Π΅Π½ΠΈΠ΅
ΠΠ°ΡΡΡΠΎΠΉΠ²Π°Π½Π΅ Π½Π° Travis CI
Π©Π΅ Π½ΠΈ ΡΡΡΠ±Π²Π° Ρ
ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅ Π² GitHub, ΠΊΡΠ΄Π΅ΡΠΎ ΡΠ΅ Π½Π°ΠΌΠΈΡΠ° Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΈΡΡ Π½ΠΈ ΠΏΡΠΎΠ΅ΠΊΡ, ΠΊΠ°ΠΊΡΠΎ ΠΈ ΠΊΠ»ΡΡ Π·Π° PVS-Studio (ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΏΠΎΠ»ΡΡΠΈΡΠ΅
ΠΠ° ΠΎΡΠΈΠ΄Π΅ΠΌ Π½Π° ΡΠ°ΠΉΡΠ°
ΠΠ° ΡΠ΅ΡΡΠ° ΡΠ°Π·ΠΊΠ»ΠΎΠ½ΠΈΡ
PPSSPP.
ΠΠΊΡΠΈΠ²ΠΈΡΠ°ΠΌΠ΅ Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅ΡΠΎ, ΠΊΠΎΠ΅ΡΠΎ ΠΈΡΠΊΠ°ΠΌΠ΅ Π΄Π° ΡΡΠ±Π΅ΡΠ΅ΠΌ:
Π ΠΌΠΎΠΌΠ΅Π½ΡΠ° Travis CI Π½Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠ·Π³ΡΠ°Π΄ΠΈ Π½Π°ΡΠΈΡ ΠΏΡΠΎΠ΅ΠΊΡ, Π·Π°ΡΠΎΡΠΎ Π½ΡΠΌΠ° ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ Π·Π° ΠΈΠ·Π³ΡΠ°ΠΆΠ΄Π°Π½Π΅. Π’Π°ΠΊΠ° ΡΠ΅ Π΅ Π²ΡΠ΅ΠΌΠ΅ Π·Π° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ.
ΠΠΎ Π²ΡΠ΅ΠΌΠ΅ Π½Π° Π°Π½Π°Π»ΠΈΠ·Π° Π½ΡΠΊΠΎΠΈ ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈ ΡΠ΅ Π½ΠΈ Π±ΡΠ΄Π°Ρ ΠΏΠΎΠ»Π΅Π·Π½ΠΈ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ ΠΊΠ»ΡΡΡΡ Π·Π° PVS-Studio, ΠΊΠΎΠΉΡΠΎ Π±ΠΈ Π±ΠΈΠ»ΠΎ Π½Π΅ΠΆΠ΅Π»Π°ΡΠ΅Π»Π½ΠΎ Π΄Π° ΡΠ΅ ΠΏΠΎΡΠΎΡΠΈ Π² ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π½ΠΈΡ ΡΠ°ΠΉΠ». Π’Π°ΠΊΠ° ΡΠ΅ Π½Π΅ΠΊΠ° Π΄ΠΎΠ±Π°Π²ΠΈΠΌ ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈ Π½Π° ΡΡΠ΅Π΄Π°ΡΠ°, ΠΊΠ°ΡΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈΡΠ΅ Π·Π° ΠΈΠ·Π³ΡΠ°ΠΆΠ΄Π°Π½Π΅ Π² Travis CI:
ΠΠΌΠ°ΠΌΠ΅ Π½ΡΠΆΠ΄Π° ΠΎΡ:
- PVS_USERNAME - ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠΎ ΠΈΠΌΠ΅
- PVS_KEY - ΠΊΠ»ΡΡ
- MAIL_USER - ΠΈΠΌΠ΅ΠΉΠ», ΠΊΠΎΠΉΡΠΎ ΡΠ΅ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π·Π° ΠΈΠ·ΠΏΡΠ°ΡΠ°Π½Π΅ Π½Π° ΠΎΡΡΠ΅ΡΠ°
- MAIL_PASSWORD - ΠΈΠΌΠ΅ΠΉΠ» ΠΏΠ°ΡΠΎΠ»Π°
ΠΠΎΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ Π΄Π²Π΅ Π½Π΅ ΡΠ° Π·Π°Π΄ΡΠ»ΠΆΠΈΡΠ΅Π»Π½ΠΈ. Π’Π΅ ΡΠ΅ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ Π·Π° ΠΈΠ·ΠΏΡΠ°ΡΠ°Π½Π΅ Π½Π° ΡΠ΅Π·ΡΠ»ΡΠ°ΡΠΈΡΠ΅ ΠΏΠΎ ΠΏΠΎΡΠ°ΡΠ°. ΠΠΊΠΎ ΠΈΡΠΊΠ°ΡΠ΅ Π΄Π° ΡΠ°Π·ΠΏΡΠΎΡΡΡΠ°Π½ΠΈΡΠ΅ Π΄ΠΎΠΊΠ»Π°Π΄Π° ΠΏΠΎ Π΄ΡΡΠ³ Π½Π°ΡΠΈΠ½, Π½Π΅ Π΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° Π³ΠΈ ΠΏΠΎΡΠΎΡΠ²Π°ΡΠ΅.
Π ΡΠ°ΠΊΠ°, Π΄ΠΎΠ±Π°Π²ΠΈΡ ΠΌΠ΅ ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈΡΠ΅ Π½Π° ΡΡΠ΅Π΄Π°ΡΠ°, ΠΎΡ ΠΊΠΎΠΈΡΠΎ ΡΠ΅ Π½ΡΠΆΠ΄Π°Π΅ΠΌ:
Π‘Π΅Π³Π° Π½Π΅ΠΊΠ° ΡΡΠ·Π΄Π°Π΄Π΅ΠΌ ΡΠ°ΠΉΠ» .travis.yml ΠΈ Π³ΠΎ ΠΏΠΎΡΡΠ°Π²Π΅ΡΠ΅ Π² ΠΊΠΎΡΠ΅Π½Π° Π½Π° ΠΏΡΠΎΠ΅ΠΊΡΠ°. PPSSPP Π²Π΅ΡΠ΅ ΠΈΠΌΠ°ΡΠ΅ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π΅Π½ ΡΠ°ΠΉΠ» Π·Π° Travis CI, Π½ΠΎ ΡΠΎΠΉ Π±Π΅ΡΠ΅ ΡΠ²ΡΡΠ΄Π΅ Π³ΠΎΠ»ΡΠΌ ΠΈ Π½Π°ΠΏΡΠ»Π½ΠΎ Π½Π΅ΠΏΠΎΠ΄Ρ
ΠΎΠ΄ΡΡ Π·Π° ΠΏΡΠΈΠΌΠ΅ΡΠ°, ΡΠ°ΠΊΠ° ΡΠ΅ ΡΡΡΠ±Π²Π°ΡΠ΅ Π·Π½Π°ΡΠΈΡΠ΅Π»Π½ΠΎ Π΄Π° Π³ΠΎ ΠΎΠΏΡΠΎΡΡΠΈΠΌ ΠΈ Π΄Π° ΠΎΡΡΠ°Π²ΠΈΠΌ ΡΠ°ΠΌΠΎ ΠΎΡΠ½ΠΎΠ²Π½ΠΈΡΠ΅ Π΅Π»Π΅ΠΌΠ΅Π½ΡΠΈ.
ΠΡΡΠ²ΠΎ, Π½Π΅ΠΊΠ° ΠΏΠΎΡΠΎΡΠΈΠΌ Π΅Π·ΠΈΠΊΠ°, Π²Π΅ΡΡΠΈΡΡΠ° Π½Π° Ubuntu Linux, ΠΊΠΎΡΡΠΎ ΠΈΡΠΊΠ°ΠΌΠ΅ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ Π²ΡΠ² Π²ΠΈΡΡΡΠ°Π»Π½Π°ΡΠ° ΠΌΠ°ΡΠΈΠ½Π°, ΠΈ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΈΡΠ΅ ΠΏΠ°ΠΊΠ΅ΡΠΈ Π·Π° ΠΊΠΎΠΌΠΏΠΈΠ»Π°ΡΠΈΡΡΠ°:
language: cpp
dist: xenial
addons:
apt:
update: true
packages:
- ant
- aria2
- build-essential
- cmake
- libgl1-mesa-dev
- libglu1-mesa-dev
- libsdl2-dev
- pv
- sendemail
- software-properties-common
sources:
- sourceline: 'ppa:ubuntu-toolchain-r/test'
- sourceline: 'ppa:ubuntu-sdk-team/ppa'
ΠΡΠΈΡΠΊΠΈ ΠΈΠ·Π±ΡΠΎΠ΅Π½ΠΈ ΠΏΠ°ΠΊΠ΅ΡΠΈ ΡΠ° Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΈ ΠΈΠ·ΠΊΠ»ΡΡΠΈΡΠ΅Π»Π½ΠΎ Π·Π° PPSSPP.
Π‘Π΅Π³Π° ΠΏΠΎΡΠΎΡΠ²Π°ΠΌΠ΅ ΠΌΠ°ΡΡΠΈΡΠ°ΡΠ° Π½Π° ΡΠ³Π»ΠΎΠ±ΡΠ²Π°Π½Π΅:
matrix:
include:
- os: linux
compiler: "gcc"
env: PPSSPP_BUILD_TYPE=Linux PVS_ANALYZE=Yes
- os: linux
compiler: "clang"
env: PPSSPP_BUILD_TYPE=Linux
ΠΡΠ΅ ΠΌΠ°Π»ΠΊΠΎ Π·Π° ΡΠ΅ΠΊΡΠΈΡΡΠ° ΠΌΠ°ΡΡΠΈΡΠ°. Π Travis CI ΠΈΠΌΠ° Π΄Π²Π° Π½Π°ΡΠΈΠ½Π° Π·Π° ΡΡΠ·Π΄Π°Π²Π°Π½Π΅ Π½Π° ΠΎΠΏΡΠΈΠΈ Π·Π° ΠΈΠ·Π³ΡΠ°ΠΆΠ΄Π°Π½Π΅: ΠΏΡΡΠ²ΠΈΡΡ Π΅ Π΄Π° ΡΠ΅ ΠΏΠΎΡΠΎΡΠΈ ΡΠΏΠΈΡΡΠΊ Ρ ΠΊΠΎΠΌΠΏΠΈΠ»Π°ΡΠΎΡΠΈ, ΡΠΈΠΏΠΎΠ²Π΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΎΠ½Π½ΠΈ ΡΠΈΡΡΠ΅ΠΌΠΈ, ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈ Π½Π° ΡΡΠ΅Π΄Π°ΡΠ° ΠΈ Ρ.Π½., ΡΠ»Π΅Π΄ ΠΊΠΎΠ΅ΡΠΎ ΡΠ΅ Π³Π΅Π½Π΅ΡΠΈΡΠ° ΠΌΠ°ΡΡΠΈΡΠ° ΠΎΡ Π²ΡΠΈΡΠΊΠΈ Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΈ ΠΊΠΎΠΌΠ±ΠΈΠ½Π°ΡΠΈΠΈ; Π²ΡΠΎΡΠΎΡΠΎ Π΅ ΠΈΠ·ΡΠΈΡΠ½ΠΎ ΡΠΊΠ°Π·Π°Π½ΠΈΠ΅ Π½Π° ΠΌΠ°ΡΡΠΈΡΠ°ΡΠ°. Π Π°Π·Π±ΠΈΡΠ° ΡΠ΅, ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡΠ°ΡΠ΅ ΡΠ΅Π·ΠΈ Π΄Π²Π° ΠΏΠΎΠ΄Ρ
ΠΎΠ΄Π° ΠΈ Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΡΠ΅ ΡΠ½ΠΈΠΊΠ°Π»Π΅Π½ ΡΠ»ΡΡΠ°ΠΉ ΠΈΠ»ΠΈ, Π½Π°ΠΏΡΠΎΡΠΈΠ², Π΄Π° Π³ΠΎ ΠΈΠ·ΠΊΠ»ΡΡΠΈΡΠ΅, ΠΊΠ°ΡΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΡΠ΅ ΡΠ΅ΠΊΡΠΈΡΡΠ° ΠΈΠ·ΠΊΠ»ΡΡΠ²Π°ΠΌ. ΠΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΏΡΠΎΡΠ΅ΡΠ΅ΡΠ΅ ΠΏΠΎΠ²Π΅ΡΠ΅ Π·Π° ΡΠΎΠ²Π° Π²
ΠΡΠΈΡΠΊΠΎ, ΠΊΠΎΠ΅ΡΠΎ ΠΎΡΡΠ°Π²Π°, Π΅ Π΄Π° ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²ΠΈΡΠ΅ ΡΠΏΠ΅ΡΠΈΡΠΈΡΠ½ΠΈ Π·Π° ΠΏΡΠΎΠ΅ΠΊΡΠ° ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ Π·Π° ΡΠ³Π»ΠΎΠ±ΡΠ²Π°Π½Π΅:
before_install:
- travis_retry bash .travis.sh travis_before_install
install:
- travis_retry bash .travis.sh travis_install
script:
- bash .travis.sh travis_script
after_success:
- bash .travis.sh travis_after_success
Travis CI Π²ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ²Π° Π΄Π° Π΄ΠΎΠ±Π°Π²ΡΡΠ΅ ΡΠ²ΠΎΠΈ ΡΠΎΠ±ΡΡΠ²Π΅Π½ΠΈ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π·Π° ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ Π΅ΡΠ°ΠΏΠΈ ΠΎΡ ΠΆΠΈΠ²ΠΎΡΠ° Π½Π° Π²ΠΈΡΡΡΠ°Π»Π½Π° ΠΌΠ°ΡΠΈΠ½Π°. Π Π°Π·Π΄Π΅Π» ΠΏΡΠ΅Π΄ΠΈ_ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°Π½Π΅ ΡΠ΅ ΠΈΠ·ΠΏΡΠ»Π½ΡΠ²Π° ΠΏΡΠ΅Π΄ΠΈ ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°Π½Π΅ Π½Π° ΠΏΠ°ΠΊΠ΅ΡΠΈ. Π’ΠΎΠ³Π°Π²Π° ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°ΠΌ, ΠΊΠΎΠ΅ΡΠΎ ΡΠ»Π΅Π΄Π²Π° ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°Π½Π΅ΡΠΎ Π½Π° ΠΏΠ°ΠΊΠ΅ΡΠΈ ΠΎΡ ΡΠΏΠΈΡΡΠΊΠ° addons.aptΠΊΠΎΠΈΡΠΎ ΠΏΠΎΡΠΎΡΠΈΡ
ΠΌΠ΅ ΠΏΠΎ-Π³ΠΎΡΠ΅. Π‘Π°ΠΌΠΎΡΠΎ ΡΠ³Π»ΠΎΠ±ΡΠ²Π°Π½Π΅ ΡΠ΅ ΠΈΠ·Π²ΡΡΡΠ²Π° Π² ΠΏΠΈΡΠΌΠ΅Π½ΠΎΡΡ. ΠΠΊΠΎ Π²ΡΠΈΡΠΊΠΎ Π΅ ΠΌΠΈΠ½Π°Π»ΠΎ Π΄ΠΎΠ±ΡΠ΅, Π·Π½Π°ΡΠΈ ΡΠ΅ ΡΠ΅ ΠΎΠ·ΠΎΠ²Π΅ΠΌ ΡΠ»Π΅Π΄_ΡΡΠΏΠ΅Ρ
(ΠΈΠΌΠ΅Π½Π½ΠΎ Π² ΡΠΎΠ·ΠΈ ΡΠ°Π·Π΄Π΅Π» ΡΠ΅ ΠΏΡΠΎΠ²Π΅Π΄Π΅ΠΌ ΡΡΠ°ΡΠΈΡΠ΅Π½ Π°Π½Π°Π»ΠΈΠ·). Π’ΠΎΠ²Π° Π½Π΅ ΡΠ° Π²ΡΠΈΡΠΊΠΈ ΡΡΡΠΏΠΊΠΈ, ΠΊΠΎΠΈΡΠΎ ΠΌΠΎΠ³Π°Ρ Π΄Π° Π±ΡΠ΄Π°Ρ ΠΌΠΎΠ΄ΠΈΡΠΈΡΠΈΡΠ°Π½ΠΈ, Π°ΠΊΠΎ ΠΈΠΌΠ°ΡΠ΅ Π½ΡΠΆΠ΄Π° ΠΎΡ ΠΏΠΎΠ²Π΅ΡΠ΅, ΡΠΎΠ³Π°Π²Π° ΡΡΡΠ±Π²Π° Π΄Π° ΡΠ°Π·Π³Π»Π΅Π΄Π°ΡΠ΅
ΠΠ° ΠΏΠΎ-Π»Π΅ΡΠ½ΠΎ ΡΠ΅ΡΠ΅Π½Π΅ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈΡΠ΅ Π±ΡΡ Π° ΠΏΠΎΡΡΠ°Π²Π΅Π½ΠΈ Π² ΠΎΡΠ΄Π΅Π»Π΅Π½ ΡΠΊΡΠΈΠΏΡ .travis.sh, ΠΊΠΎΠΉΡΠΎ ΡΠ΅ ΠΏΠΎΡΡΠ°Π²Ρ Π² ΠΎΡΠ½ΠΎΠ²Π°ΡΠ° Π½Π° ΠΏΡΠΎΠ΅ΠΊΡΠ°.
Π’Π°ΠΊΠ° ΡΠ΅ ΠΈΠΌΠ°ΠΌΠ΅ ΡΠ»Π΅Π΄Π½ΠΈΡ ΡΠ°ΠΉΠ» .travis.yml:
language: cpp
dist: xenial
addons:
apt:
update: true
packages:
- ant
- aria2
- build-essential
- cmake
- libgl1-mesa-dev
- libglu1-mesa-dev
- libsdl2-dev
- pv
- sendemail
- software-properties-common
sources:
- sourceline: 'ppa:ubuntu-toolchain-r/test'
- sourceline: 'ppa:ubuntu-sdk-team/ppa'
matrix:
include:
- os: linux
compiler: "gcc"
env: PVS_ANALYZE=Yes
- os: linux
compiler: "clang"
before_install:
- travis_retry bash .travis.sh travis_before_install
install:
- travis_retry bash .travis.sh travis_install
script:
- bash .travis.sh travis_script
after_success:
- bash .travis.sh travis_after_success
ΠΡΠ΅Π΄ΠΈ Π΄Π° ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°ΠΌΠ΅ ΠΏΠ°ΠΊΠ΅ΡΠΈΡΠ΅, ΡΠ΅ Π°ΠΊΡΡΠ°Π»ΠΈΠ·ΠΈΡΠ°ΠΌΠ΅ ΠΏΠΎΠ΄ΠΌΠΎΠ΄ΡΠ»ΠΈΡΠ΅. Π’ΠΎΠ²Π° Π΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π·Π° ΠΈΠ·Π³ΡΠ°ΠΆΠ΄Π°Π½Π΅ Π½Π° PPSSPP. ΠΠ΅ΠΊΠ° Π΄ΠΎΠ±Π°Π²ΠΈΠΌ ΠΏΡΡΠ²Π°ΡΠ° ΡΡΠ½ΠΊΡΠΈΡ ΠΊΡΠΌ .travis.sh (ΠΎΠ±ΡΡΠ½Π΅ΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΡΠ°Π·ΡΠΈΡΠ΅Π½ΠΈΠ΅ΡΠΎ):
travis_before_install() {
git submodule update --init --recursive
}
Π‘Π΅Π³Π° ΡΡΠΈΠ³Π°ΠΌΠ΅ Π΄ΠΈΡΠ΅ΠΊΡΠ½ΠΎ Π΄ΠΎ Π½Π°ΡΡΡΠΎΠΉΠΊΠ°ΡΠ° Π½Π° Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ½ΠΎΡΠΎ ΡΡΠ°ΡΡΠΈΡΠ°Π½Π΅ Π½Π° PVS-Studio Π² Travis CI. ΠΡΡΠ²ΠΎ ΡΡΡΠ±Π²Π° Π΄Π° ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°ΠΌΠ΅ ΠΏΠ°ΠΊΠ΅ΡΠ° PVS-Studio Π² ΡΠΈΡΡΠ΅ΠΌΠ°ΡΠ°:
travis_install() {
if [ "$CXX" = "g++" ]; then
sudo apt-get install -qq g++-4.8
fi
if [ "$PVS_ANALYZE" = "Yes" ]; then
wget -q -O - https://files.viva64.com/etc/pubkey.txt
| sudo apt-key add -
sudo wget -O /etc/apt/sources.list.d/viva64.list
https://files.viva64.com/etc/viva64.list
sudo apt-get update -qq
sudo apt-get install -qq pvs-studio
libio-socket-ssl-perl
libnet-ssleay-perl
fi
download_extract
"https://cmake.org/files/v3.6/cmake-3.6.2-Linux-x86_64.tar.gz"
cmake-3.6.2-Linux-x86_64.tar.gz
}
Π Π½Π°ΡΠ°Π»ΠΎΡΠΎ Π½Π° ΡΡΠ½ΠΊΡΠΈΡΡΠ° travis_install Π½ΠΈΠ΅ ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°ΠΌΠ΅ ΠΊΠΎΠΌΠΏΠΈΠ»Π°ΡΠΎΡΠΈΡΠ΅, ΠΎΡ ΠΊΠΎΠΈΡΠΎ ΡΠ΅ Π½ΡΠΆΠ΄Π°Π΅ΠΌ, ΠΊΠ°ΡΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈ Π½Π° ΡΡΠ΅Π΄Π°ΡΠ°. Π’ΠΎΠ³Π°Π²Π°, Π°ΠΊΠΎ ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π°ΡΠ° $PVS_ANALYZE ΡΡΡ ΡΠ°Π½ΡΠ²Π° ΡΡΠΎΠΉΠ½ΠΎΡΡ ΠΠ° (ΠΏΠΎΡΠΎΡΠΈΠ»ΠΈ ΡΠΌΠ΅ Π³ΠΎ Π² ΡΠ°Π·Π΄Π΅Π»Π° ΠΠΊΠΎΠ»Π½Π° ΡΡΠ΅Π΄Π° ΠΏΠΎ Π²ΡΠ΅ΠΌΠ΅ Π½Π° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡΡΠ° Π½Π° ΠΌΠ°ΡΡΠΈΡΠ°ΡΠ° Π·Π° ΠΈΠ·Π³ΡΠ°ΠΆΠ΄Π°Π½Π΅), ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°ΠΌΠ΅ ΠΏΠ°ΠΊΠ΅ΡΠ° pvs-ΡΡΡΠ΄ΠΈΠΎ. Π Π΄ΠΎΠΏΡΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊΡΠΌ ΡΠΎΠ²Π° ΡΠ° ΠΏΠΎΡΠΎΡΠ΅Π½ΠΈ ΠΈ ΠΏΠ°ΠΊΠ΅ΡΠΈ libio-socket-ssl-perl ΠΈ libnet-ssleay-perl, ΠΎΠ±Π°ΡΠ΅, ΡΠ΅ ΡΠ° Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΈ Π·Π° ΠΈΠ·ΠΏΡΠ°ΡΠ°Π½Π΅ Π½Π° ΡΠ΅Π·ΡΠ»ΡΠ°ΡΠΈΡΠ΅ ΠΏΠΎ ΠΏΠΎΡΠ°ΡΠ°, ΡΠ°ΠΊΠ° ΡΠ΅ Π½Π΅ ΡΠ° Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΈ, Π°ΠΊΠΎ ΡΡΠ΅ ΠΈΠ·Π±ΡΠ°Π»ΠΈ Π΄ΡΡΠ³ ΠΌΠ΅ΡΠΎΠ΄ Π·Π° Π΄ΠΎΡΡΠ°Π²ΡΠ½Π΅ Π½Π° Π²Π°ΡΠΈΡ ΠΎΡΡΠ΅Ρ.
Π€ΡΠ½ΠΊΡΠΈΡ ΠΈΠ·ΡΠ΅Π³Π»ΡΠ½Π΅_Π΅ΠΊΡΡΡΠ°ΠΊΡ ΠΈΠ·ΡΠ΅Π³Π»Ρ ΠΈ ΡΠ°Π·ΠΎΠΏΠ°ΠΊΠΎΠ²Π° ΠΏΠΎΡΠΎΡΠ΅Π½ΠΈΡ Π°ΡΡ ΠΈΠ²:
download_extract() {
aria2c -x 16 $1 -o $2
tar -xf $2
}
ΠΡΠ΅ΠΌΠ΅ Π΅ Π΄Π° ΡΠ³Π»ΠΎΠ±ΠΈΠΌ ΠΏΡΠΎΠ΅ΠΊΡΠ°. Π’ΠΎΠ²Π° ΡΠ΅ ΡΠ»ΡΡΠ²Π° Π² ΡΠ΅ΠΊΡΠΈΡΡΠ° ΠΏΠΈΡΠΌΠ΅Π½ΠΎΡΡ:
travis_script() {
if [ -d cmake-3.6.2-Linux-x86_64 ]; then
export PATH=$(pwd)/cmake-3.6.2-Linux-x86_64/bin:$PATH
fi
CMAKE_ARGS="-DHEADLESS=ON ${CMAKE_ARGS}"
if [ "$PVS_ANALYZE" = "Yes" ]; then
CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
fi
cmake $CMAKE_ARGS CMakeLists.txt
make
}
ΠΡΡΡΠ½ΠΎΡΡ ΡΠΎΠ²Π° Π΅ ΠΎΠΏΡΠΎΡΡΠ΅Π½Π° ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»Π½Π° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ, Ρ ΠΈΠ·ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π½Π° ΡΠ΅Π·ΠΈ ΡΠ΅Π΄ΠΎΠ²Π΅:
if [ "$PVS_ANALYZE" = "Yes" ]; then
CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
fi
Π ΡΠΎΠ·ΠΈ ΡΠ°Π·Π΄Π΅Π» ΠΎΡ ΠΊΠΎΠ΄Π°, ΠΊΠΎΠΉΡΠΎ ΡΠΌΠ΅ Π·Π°Π΄Π°Π»ΠΈ Π·Π° cmake ΡΠ»Π°Π³ Π·Π° Π΅ΠΊΡΠΏΠΎΡΡΠΈΡΠ°Π½Π΅ Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π·Π° ΠΊΠΎΠΌΠΏΠΈΠ»Π°ΡΠΈΡ. Π’ΠΎΠ²Π° Π΅ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ Π·Π° Π°Π½Π°Π»ΠΈΠ·Π°ΡΠΎΡ Π½Π° ΡΡΠ°ΡΠΈΡΠ΅Π½ ΠΊΠΎΠ΄. ΠΠΎΠ²Π΅ΡΠ΅ Π·Π° ΡΠΎΠ²Π° ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΏΡΠΎΡΠ΅ΡΠ΅ΡΠ΅ Π² ΡΡΠ°ΡΠΈΡΡΠ° β
ΠΠΊΠΎ ΡΠ³Π»ΠΎΠ±ΡΠ²Π°Π½Π΅ΡΠΎ Π΅ ΡΡΠΏΠ΅ΡΠ½ΠΎ, ΡΠΎΠ³Π°Π²Π° ΡΡΠΈΠ³Π°ΠΌΠ΅ Π΄ΠΎ ΡΠ»Π΅Π΄_ΡΡΠΏΠ΅Ρ , ΠΊΡΠ΄Π΅ΡΠΎ ΠΈΠ·Π²ΡΡΡΠ²Π°ΠΌΠ΅ ΡΡΠ°ΡΠΈΡΠ΅Π½ Π°Π½Π°Π»ΠΈΠ·:
travis_after_success() {
if [ "$PVS_ANALYZE" = "Yes" ]; then
pvs-studio-analyzer credentials $PVS_USERNAME $PVS_KEY -o PVS-Studio.lic
pvs-studio-analyzer analyze -j2 -l PVS-Studio.lic
-o PVS-Studio-${CC}.log
--disableLicenseExpirationCheck
plog-converter -t html PVS-Studio-${CC}.log -o PVS-Studio-${CC}.html
sendemail -t [email protected]
-u "PVS-Studio $CC report, commit:$TRAVIS_COMMIT"
-m "PVS-Studio $CC report, commit:$TRAVIS_COMMIT"
-s smtp.gmail.com:587
-xu $MAIL_USER
-xp $MAIL_PASSWORD
-o tls=yes
-f $MAIL_USER
-a PVS-Studio-${CC}.log PVS-Studio-${CC}.html
fi
}
ΠΠ΅ΠΊΠ° ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΏΠΎ-ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΠΎ ΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ ΡΠ΅Π΄ΠΎΠ²Π΅:
pvs-studio-analyzer credentials $PVS_USERNAME $PVS_KEY -o PVS-Studio.lic
pvs-studio-analyzer analyze -j2 -l PVS-Studio.lic
-o PVS-Studio-${CC}.log
--disableLicenseExpirationCheck
plog-converter -t html PVS-Studio-${CC}.log -o PVS-Studio-${CC}.html
ΠΡΡΠ²ΠΈΡΡ ΡΠ΅Π΄ Π³Π΅Π½Π΅ΡΠΈΡΠ° ΡΠ°ΠΉΠ» Ρ Π»ΠΈΡΠ΅Π½Π· ΠΎΡ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠΎΡΠΎ ΠΈΠΌΠ΅ ΠΈ ΠΊΠ»ΡΡΠ°, ΠΊΠΎΠΈΡΠΎ ΠΏΠΎΡΠΎΡΠΈΡ ΠΌΠ΅ Π² ΡΠ°ΠΌΠΎΡΠΎ Π½Π°ΡΠ°Π»ΠΎ ΠΏΡΠΈ Π½Π°ΡΡΡΠΎΠΉΠ²Π°Π½Π΅ΡΠΎ Π½Π° ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈΡΠ΅ Π½Π° ΡΡΠ΅Π΄Π°ΡΠ° Travis CI.
ΠΡΠΎΡΠΈΡΡ ΡΠ΅Π΄ ΡΡΠ°ΡΡΠΈΡΠ° Π΄ΠΈΡΠ΅ΠΊΡΠ½ΠΎ Π°Π½Π°Π»ΠΈΠ·Π°. Π€Π»Π°Π³ -j Π·Π°Π΄Π°Π²Π° Π±ΡΠΎΡ Π½Π° Π½ΠΈΡΠΊΠΈΡΠ΅ Π·Π° Π°Π½Π°Π»ΠΈΠ·, ΡΠ»Π°Π³ -Π» ΠΏΠΎΠΊΠ°Π·Π²Π° Π»ΠΈΡΠ΅Π½Π·, ΡΠ»Π°Π³ -ΠΎ Π΄Π΅ΡΠΈΠ½ΠΈΡΠ° ΡΠ°ΠΉΠ»Π° Π·Π° ΠΈΠ·Π²Π΅ΠΆΠ΄Π°Π½Π΅ Π½Π° ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΠΎΠ½Π½ΠΈ ΡΠ°ΠΉΠ»ΠΎΠ²Π΅ ΠΈ ΡΠ»Π°Π³Π° -disableLicenseExpirationCheck ΠΈΠ·ΠΈΡΠΊΠ²Π° ΡΠ΅ Π·Π° ΠΏΡΠΎΠ±Π½ΠΈ Π²Π΅ΡΡΠΈΠΈ, ΡΡΠΉ ΠΊΠ°ΡΠΎ ΠΏΠΎ ΠΏΠΎΠ΄ΡΠ°Π·Π±ΠΈΡΠ°Π½Π΅ pvs-studio-Π°Π½Π°Π»ΠΈΠ·Π°ΡΠΎΡ ΡΠ΅ ΠΏΡΠ΅Π΄ΡΠΏΡΠ΅Π΄ΠΈ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»Ρ, ΡΠ΅ Π»ΠΈΡΠ΅Π½Π·ΡΡ Π΅ Π½Π° ΠΏΡΡ Π΄Π° ΠΈΠ·ΡΠ΅ΡΠ΅. ΠΠ° Π΄Π° ΠΏΡΠ΅Π΄ΠΎΡΠ²ΡΠ°ΡΠΈΡΠ΅ ΡΠΎΠ²Π° Π΄Π° ΡΠ΅ ΡΠ»ΡΡΠΈ, ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΏΠΎΡΠΎΡΠΈΡΠ΅ ΡΠΎΠ·ΠΈ ΡΠ»Π°Π³.
Π Π΅Π³ΠΈΡΡΡΠ°ΡΠΈΠΎΠ½Π½ΠΈΡΡ ΡΠ°ΠΉΠ» ΡΡΠ΄ΡΡΠΆΠ° Π½Π΅ΠΎΠ±ΡΠ°Π±ΠΎΡΠ΅Π½ ΠΈΠ·Ρ ΠΎΠ΄, ΠΊΠΎΠΉΡΠΎ Π½Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΡΠ΄Π΅ ΠΏΡΠΎΡΠ΅ΡΠ΅Π½ Π±Π΅Π· ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΡΠ²Π°Π½Π΅, ΡΠ°ΠΊΠ° ΡΠ΅ ΠΏΡΡΠ²ΠΎ ΡΡΡΠ±Π²Π° Π΄Π° Π½Π°ΠΏΡΠ°Π²ΠΈΡΠ΅ ΡΠ°ΠΉΠ»Π° ΡΠ΅ΡΠΈΠΌ. ΠΠ΅ΠΊΠ° ΠΏΡΠ΅ΠΊΠ°ΡΠ°ΠΌΠ΅ ΡΡΡΠΏΠΈΡΠ΅ plog-ΠΊΠΎΠ½Π²Π΅ΡΡΠΎΡ, Π° ΠΈΠ·Ρ ΠΎΠ΄ΡΡ Π΅ html ΡΠ°ΠΉΠ».
Π ΡΠΎΠ·ΠΈ ΠΏΡΠΈΠΌΠ΅Ρ ΡΠ΅ΡΠΈΡ Π΄Π° ΠΈΠ·ΠΏΡΠ°ΡΠ°ΠΌ ΠΎΡΡΠ΅ΡΠΈ ΠΏΠΎ ΠΏΠΎΡΠ°ΡΠ° Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ° ΠΠ·ΠΏΡΠ°ΡΠ΅ΡΠ΅ ΠΈΠΌΠ΅ΠΉΠ».
Π ΡΠ΅Π·ΡΠ»ΡΠ°Ρ Π½Π° ΡΠΎΠ²Π° ΠΏΠΎΠ»ΡΡΠΈΡ ΠΌΠ΅ ΡΠ»Π΅Π΄Π½ΠΈΡ ΡΠ°ΠΉΠ» .travis.sh:
#/bin/bash
travis_before_install() {
git submodule update --init --recursive
}
download_extract() {
aria2c -x 16 $1 -o $2
tar -xf $2
}
travis_install() {
if [ "$CXX" = "g++" ]; then
sudo apt-get install -qq g++-4.8
fi
if [ "$PVS_ANALYZE" = "Yes" ]; then
wget -q -O - https://files.viva64.com/etc/pubkey.txt
| sudo apt-key add -
sudo wget -O /etc/apt/sources.list.d/viva64.list
https://files.viva64.com/etc/viva64.list
sudo apt-get update -qq
sudo apt-get install -qq pvs-studio
libio-socket-ssl-perl
libnet-ssleay-perl
fi
download_extract
"https://cmake.org/files/v3.6/cmake-3.6.2-Linux-x86_64.tar.gz"
cmake-3.6.2-Linux-x86_64.tar.gz
}
travis_script() {
if [ -d cmake-3.6.2-Linux-x86_64 ]; then
export PATH=$(pwd)/cmake-3.6.2-Linux-x86_64/bin:$PATH
fi
CMAKE_ARGS="-DHEADLESS=ON ${CMAKE_ARGS}"
if [ "$PVS_ANALYZE" = "Yes" ]; then
CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
fi
cmake $CMAKE_ARGS CMakeLists.txt
make
}
travis_after_success() {
if [ "$PVS_ANALYZE" = "Yes" ]; then
pvs-studio-analyzer credentials $PVS_USERNAME $PVS_KEY -o PVS-Studio.lic
pvs-studio-analyzer analyze -j2 -l PVS-Studio.lic
-o PVS-Studio-${CC}.log
--disableLicenseExpirationCheck
plog-converter -t html PVS-Studio-${CC}.log -o PVS-Studio-${CC}.html
sendemail -t [email protected]
-u "PVS-Studio $CC report, commit:$TRAVIS_COMMIT"
-m "PVS-Studio $CC report, commit:$TRAVIS_COMMIT"
-s smtp.gmail.com:587
-xu $MAIL_USER
-xp $MAIL_PASSWORD
-o tls=yes
-f $MAIL_USER
-a PVS-Studio-${CC}.log PVS-Studio-${CC}.html
fi
}
set -e
set -x
$1;
Π‘Π΅Π³Π° Π΅ Π²ΡΠ΅ΠΌΠ΅ Π΄Π° ΠΈΠ·ΠΏΡΠ°ΡΠΈΡΠ΅ ΠΏΡΠΎΠΌΠ΅Π½ΠΈΡΠ΅ Π² git Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅ΡΠΎ, ΡΠ»Π΅Π΄ ΠΊΠΎΠ΅ΡΠΎ Travis CI Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ½ΠΎ ΡΠ΅ ΡΡΠ°ΡΡΠΈΡΠ° ΠΊΠΎΠΌΠΏΠΈΠ»Π°ΡΠΈΡΡΠ°. Π©ΡΠ°ΠΊΠ½Π΅ΡΠ΅ Π²ΡΡΡ Ρ βppssppβ, Π·Π° Π΄Π° ΠΎΡΠΈΠ΄Π΅ΡΠ΅ Π½Π° ΠΎΡΡΠ΅ΡΠΈΡΠ΅ Π·Π° ΠΈΠ·Π³ΡΠ°ΠΆΠ΄Π°Π½Π΅:
Π©Π΅ Π²ΠΈΠ΄ΠΈΠΌ ΠΏΡΠ΅Π³Π»Π΅Π΄ Π½Π° ΡΠ΅ΠΊΡΡΠ°ΡΠ° ΠΊΠΎΠΌΠΏΠΈΠ»Π°ΡΠΈΡ:
ΠΠΊΠΎ ΠΈΠ·Π³ΡΠ°ΠΆΠ΄Π°Π½Π΅ΡΠΎ ΠΏΡΠΈΠΊΠ»ΡΡΠΈ ΡΡΠΏΠ΅ΡΠ½ΠΎ, ΡΠ΅ ΠΏΠΎΠ»ΡΡΠΈΠΌ ΠΈΠΌΠ΅ΠΉΠ» Ρ ΡΠ΅Π·ΡΠ»ΡΠ°ΡΠΈΡΠ΅ ΠΎΡ ΡΡΠ°ΡΠΈΡΠ½ΠΈΡ Π°Π½Π°Π»ΠΈΠ·. Π Π°Π·Π±ΠΈΡΠ° ΡΠ΅, ΠΈΠ·ΠΏΡΠ°ΡΠ°Π½Π΅ΡΠΎ ΠΏΠΎ ΠΏΠΎΡΠ°ΡΠ° Π½Π΅ Π΅ Π΅Π΄ΠΈΠ½ΡΡΠ²Π΅Π½ΠΈΡΡ Π½Π°ΡΠΈΠ½ Π΄Π° ΠΏΠΎΠ»ΡΡΠΈΡΠ΅ ΠΎΡΡΠ΅Ρ. ΠΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΈΠ·Π±Π΅ΡΠ΅ΡΠ΅ Π²ΡΠ΅ΠΊΠΈ ΠΌΠ΅ΡΠΎΠ΄ Π½Π° ΠΈΠ·ΠΏΡΠ»Π½Π΅Π½ΠΈΠ΅. ΠΠΎ Π΅ Π²Π°ΠΆΠ½ΠΎ Π΄Π° Π·Π°ΠΏΠΎΠΌΠ½ΠΈΡΠ΅, ΡΠ΅ ΡΠ»Π΅Π΄ ΠΊΠ°ΡΠΎ ΠΊΠΎΠΌΠΏΠΈΠ»Π°ΡΠΈΡΡΠ° ΠΏΡΠΈΠΊΠ»ΡΡΠΈ, Π½ΡΠΌΠ° Π΄Π° Π΅ Π²ΡΠ·ΠΌΠΎΠΆΠ΅Π½ Π΄ΠΎΡΡΡΠΏ Π΄ΠΎ ΡΠ°ΠΉΠ»ΠΎΠ²Π΅ΡΠ΅ Π½Π° Π²ΠΈΡΡΡΠ°Π»Π½Π°ΡΠ° ΠΌΠ°ΡΠΈΠ½Π°.
Π Π΅Π·ΡΠΌΠ΅ Π½Π° Π³ΡΠ΅ΡΠΊΠΈΡΠ΅
Π£ΡΠΏΠ΅ΡΠ½ΠΎ Π·Π°Π²ΡΡΡΠΈΡ ΠΌΠ΅ Π½Π°ΠΉ-ΡΡΡΠ΄Π½Π°ΡΠ° ΡΠ°ΡΡ. Π‘Π΅Π³Π° Π½Π΅ΠΊΠ° ΡΠ΅ ΡΠ²Π΅ΡΠΈΠΌ, ΡΠ΅ Π²ΡΠΈΡΠΊΠΈΡΠ΅ Π½ΠΈ ΡΡΠΈΠ»ΠΈΡ ΡΠΈ Π·Π°ΡΠ»ΡΠΆΠ°Π²Π°Ρ. ΠΠ΅ΠΊΠ° Π΄Π° ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ Π½ΡΠΊΠΎΠΈ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½ΠΈ ΡΠΎΡΠΊΠΈ ΠΎΡ Π΄ΠΎΠΊΠ»Π°Π΄Π° Π·Π° ΡΡΠ°ΡΠΈΡΠ΅Π½ Π°Π½Π°Π»ΠΈΠ·, ΠΊΠΎΠΉΡΠΎ ΠΌΠΈ Π΄ΠΎΠΉΠ΄Π΅ ΠΏΠΎ ΠΏΠΎΡΠ°ΡΠ° (Π½Π΅ Π½Π°ΠΏΡΠ°Π·Π½ΠΎ Π³ΠΎ ΠΏΠΎΡΠΎΡΠΈΡ ).
ΠΠΏΠ°ΡΠ½Π° ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΡ
void sha1( unsigned char *input, int ilen, unsigned char output[20] )
{
sha1_context ctx;
sha1_starts( &ctx );
sha1_update( &ctx, input, ilen );
sha1_finish( &ctx, output );
memset( &ctx, 0, sizeof( sha1_context ) );
}
PVS-Studio ΠΏΡΠ΅Π΄ΡΠΏΡΠ΅ΠΆΠ΄Π΅Π½ΠΈΠ΅:
Π’Π°Π·ΠΈ ΡΠ°ΡΡ ΠΎΡ ΠΊΠΎΠ΄Π° ΡΠ΅ Π½Π°ΠΌΠΈΡΠ° Π² ΠΌΠΎΠ΄ΡΠ»Π° Π·Π° Π·Π°ΡΠΈΡΠ΅Π½ΠΎ Ρ
Π΅ΡΠΈΡΠ°Π½Π΅, Π½ΠΎ ΡΡΠ΄ΡΡΠΆΠ° ΡΠ΅ΡΠΈΠΎΠ·Π΅Π½ ΠΏΡΠΎΠΏΡΡΠΊ Π² ΡΠΈΠ³ΡΡΠ½ΠΎΡΡΡΠ° (
; Line 355
mov r8d, 20
xor edx, edx
lea rcx, QWORD PTR sum$[rsp]
call memset
; Line 356
ΠΡΠΈΡΠΊΠΎ Π΅ ΠΈΠ·ΡΡΠ΄Π½ΠΎ ΠΈ ΡΡΠ½ΠΊΡΠΈΠΎΠ½ΠΈΡΠ° ΠΌΠ΅ΠΌΠ΅ΡΠ΅Ρ ΡΠ΅ ΠΈΠ·ΠΏΡΠ»Π½ΡΠ²Π°, ΠΊΠ°ΡΠΎ ΠΏΠΎ ΡΠΎΠ·ΠΈ Π½Π°ΡΠΈΠ½ ΠΏΡΠ΅Π·Π°ΠΏΠΈΡΠ²Π° Π²Π°ΠΆΠ½ΠΈ Π΄Π°Π½Π½ΠΈ Π² RAM, Π½ΠΎ Π²ΡΠ΅ ΠΎΡΠ΅ Π½Π΅ ΡΠ΅ ΡΠ°Π΄Π²Π°ΠΉΡΠ΅. ΠΠ΅ΠΊΠ° Π΄Π° ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΡΠΏΠΈΡΡΠΊΠ° Π·Π° ΡΠ³Π»ΠΎΠ±ΡΠ²Π°Π½Π΅ Π½Π° Π²Π΅ΡΡΠΈΡΡΠ° Release Ρ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΡ:
; 354 :
; 355 : memset( sum, 0, sizeof( sum ) );
; 356 :}
ΠΠ°ΠΊΡΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ Π²ΠΈΠ΄ΠΈ ΠΎΡ Π»ΠΈΡΡΠΈΠ½Π³Π°, ΠΊΠΎΠΌΠΏΠΈΠ»Π°ΡΠΎΡΡΡ Π΅ ΠΏΡΠ΅Π½Π΅Π±ΡΠ΅Π³Π½Π°Π» ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅ΡΠΎ ΠΌΠ΅ΠΌΠ΅ΡΠ΅Ρ. Π’ΠΎΠ²Π° ΡΠ΅ Π΄ΡΠ»ΠΆΠΈ Π½Π° ΡΠ°ΠΊΡΠ°, ΡΠ΅ Π²ΡΠ² ΡΡΠ½ΠΊΡΠΈΡΡΠ° sha1 ΡΠ»Π΅Π΄ ΠΎΠ±Π°ΠΆΠ΄Π°Π½Π΅ΡΠΎ ΠΌΠ΅ΠΌΠ΅ΡΠ΅Ρ Π½ΡΠΌΠ° ΠΏΠΎΠ²Π΅ΡΠ΅ ΠΏΡΠ΅ΠΏΡΠ°ΡΠΊΠΈ ΠΊΡΠΌ ΡΡΡΡΠΊΡΡΡΠ°ΡΠ° ctx. Π‘Π»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»Π½ΠΎ ΠΊΠΎΠΌΠΏΠΈΠ»Π°ΡΠΎΡΡΡ Π½Π΅ Π²ΠΈΠΆΠ΄Π° ΡΠΌΠΈΡΡΠ» Π΄Π° Π³ΡΠ±ΠΈ ΠΏΡΠΎΡΠ΅ΡΠΎΡΠ½ΠΎ Π²ΡΠ΅ΠΌΠ΅ Π·Π° ΠΏΡΠ΅Π·Π°ΠΏΠΈΡΠ²Π°Π½Π΅ Π½Π° ΠΏΠ°ΠΌΠ΅Ρ, ΠΊΠΎΡΡΠΎ Π½Π΅ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π² Π±ΡΠ΄Π΅ΡΠ΅. ΠΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΊΠΎΡΠΈΠ³ΠΈΡΠ°ΡΠ΅ ΡΠΎΠ²Π°, ΠΊΠ°ΡΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΡΡΠ° RtlSecureZeroMemory ΠΈΠ»ΠΈ
Π²ΡΡΠ½Π°:
void sha1( unsigned char *input, int ilen, unsigned char output[20] )
{
sha1_context ctx;
sha1_starts( &ctx );
sha1_update( &ctx, input, ilen );
sha1_finish( &ctx, output );
RtlSecureZeroMemory(&ctx, sizeof( sha1_context ) );
}
ΠΠ·Π»ΠΈΡΠ½ΠΎ ΡΡΠ°Π²Π½Π΅Π½ΠΈΠ΅
static u32 sceAudioOutputPannedBlocking
(u32 chan, int leftvol, int rightvol, u32 samplePtr) {
int result = 0;
// For some reason, this is the only one that checks for negative.
if (leftvol > 0xFFFF || rightvol > 0xFFFF || leftvol < 0 || rightvol < 0) {
....
} else {
if (leftvol >= 0) {
chans[chan].leftVolume = leftvol;
}
if (rightvol >= 0) {
chans[chan].rightVolume = rightvol;
}
chans[chan].sampleAddress = samplePtr;
result = __AudioEnqueue(chans[chan], chan, true);
}
}
PVS-Studio ΠΏΡΠ΅Π΄ΡΠΏΡΠ΅ΠΆΠ΄Π΅Π½ΠΈΠ΅:
ΠΠ±ΡΡΠ½Π΅ΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΠΊΠ»ΠΎΠ½Π° else Π·Π° ΠΏΡΡΠ²ΠΈΡ if. ΠΠΎΠ΄ΡΡ ΡΠ΅ Π±ΡΠ΄Π΅ ΠΈΠ·ΠΏΡΠ»Π½Π΅Π½ ΡΠ°ΠΌΠΎ Π°ΠΊΠΎ ΡΠ° ΠΈΠ·ΠΏΡΠ»Π½Π΅Π½ΠΈ Π²ΡΠΈΡΠΊΠΈ ΡΡΠ»ΠΎΠ²ΠΈΡ leftvol > 0xFFFF || ΠΏΡΠ°Π² Π·Π²ΡΠΊ > 0xFFFF || Π»ΡΠ² ΠΎΠ±Π΅ΠΌ < 0 || ΠΏΡΠ°Π² ΠΎΠ±Π΅ΠΌ < 0 ΡΠ΅ ΡΠ΅ ΠΎΠΊΠ°ΠΆΠ΅ Π½Π΅Π²ΡΡΠ½ΠΎ. Π‘Π»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»Π½ΠΎ ΠΏΠΎΠ»ΡΡΠ°Π²Π°ΠΌΠ΅ ΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ ΡΠ²ΡΡΠ΄Π΅Π½ΠΈΡ, ΠΊΠΎΠΈΡΠΎ ΡΠ΅ Π±ΡΠ΄Π°Ρ Π²Π΅ΡΠ½ΠΈ Π·Π° ΠΊΠ»ΠΎΠ½ else: Π»ΡΠ² ΠΎΠ±Π΅ΠΌ <= 0xFFFF, ΠΏΡΠ°Π² ΠΎΠ±Π΅ΠΌ <= 0xFFFF, Π»ΡΠ² ΠΎΠ±Π΅ΠΌ >= 0 ΠΈ ΠΏΡΠ°Π² ΠΎΠ±Π΅ΠΌ >= 0. ΠΠ±ΡΡΠ½Π΅ΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ Π΄Π²Π΅ ΡΠ²ΡΡΠ΄Π΅Π½ΠΈΡ. ΠΠΌΠ° Π»ΠΈ ΡΠΌΠΈΡΡΠ» Π΄Π° ΡΠ΅ ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π° ΠΊΠΎΠ΅ Π΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΠΎ ΡΡΠ»ΠΎΠ²ΠΈΠ΅ Π·Π° ΠΈΠ·ΠΏΡΠ»Π½Π΅Π½ΠΈΠ΅ΡΠΎ Π½Π° ΡΠΎΠ·ΠΈ ΠΊΠΎΠ΄?
Π’Π°ΠΊΠ° ΡΠ΅ ΠΌΠΎΠΆΠ΅ΠΌ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎ Π΄Π° ΠΏΡΠ΅ΠΌΠ°Ρ Π½Π΅ΠΌ ΡΠ΅Π·ΠΈ ΡΡΠ»ΠΎΠ²Π½ΠΈ ΠΈΠ·ΡΠ°Π·ΠΈ:
static u32 sceAudioOutputPannedBlocking
(u32 chan, int leftvol, int rightvol, u32 samplePtr) {
int result = 0;
// For some reason, this is the only one that checks for negative.
if (leftvol > 0xFFFF || rightvol > 0xFFFF || leftvol < 0 || rightvol < 0) {
....
} else {
chans[chan].leftVolume = leftvol;
chans[chan].rightVolume = rightvol;
chans[chan].sampleAddress = samplePtr;
result = __AudioEnqueue(chans[chan], chan, true);
}
}
ΠΡΡΠ³ ΡΡΠ΅Π½Π°ΡΠΈΠΉ. ΠΠΌΠ° Π½ΡΠΊΠ°ΠΊΡΠ² Π²ΠΈΠ΄ Π³ΡΠ΅ΡΠΊΠ°, ΡΠΊΡΠΈΡΠ° Π·Π°Π΄ ΡΠ΅Π·ΠΈ ΠΈΠ·Π»ΠΈΡΠ½ΠΈ ΡΡΠ»ΠΎΠ²ΠΈΡ. ΠΠΎΠΆΠ΅ Π±ΠΈ Π½Π΅ ΡΠ° ΠΏΡΠΎΠ²Π΅ΡΠΈΠ»ΠΈ ΡΠΎΠ²Π°, ΠΊΠΎΠ΅ΡΠΎ ΡΠ΅ ΠΈΠ·ΠΈΡΠΊΠ²Π°.
Ctrl+C Ctrl+V ΠΎΡΠ²ΡΡΡΠ° Π½Π° ΡΠ΄Π°ΡΠ°
static u32 scePsmfSetPsmf(u32 psmfStruct, u32 psmfData) {
if (!Memory::IsValidAddress(psmfData) ||
!Memory::IsValidAddress(psmfData)) {
return hleReportError(ME, SCE_KERNEL_ERROR_ILLEGAL_ADDRESS, "bad address");
}
....
}
ΠΠ±ΡΡΠ½Π΅ΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΡΠ΅ΠΊΠ° Π²ΡΡΡΠ΅ if. ΠΠ΅ ΠΌΠΈΡΠ»ΠΈΡΠ΅ Π»ΠΈ, ΡΠ΅ Π΅ ΡΡΡΠ°Π½Π½ΠΎ, ΡΠ΅ ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π°ΠΌΠ΅ Π΄Π°Π»ΠΈ Π°Π΄ΡΠ΅ΡΠ° Π΅ Π²Π°Π»ΠΈΠ΄Π΅Π½? psmfData, Π΄Π²ΠΎΠΉΠ½ΠΎ ΠΏΠΎΠ²Π΅ΡΠ΅? Π’Π°ΠΊΠ° ΡΠ΅ ΡΠΎΠ²Π° ΠΌΠΈ ΡΠ΅ ΡΡΡΡΠ²Π° ΡΡΡΠ°Π½Π½ΠΎ... ΠΡΡΡΠ½ΠΎΡΡ ΡΠΎΠ²Π°, ΡΠ°Π·Π±ΠΈΡΠ° ΡΠ΅, Π΅ ΠΏΠ΅ΡΠ°ΡΠ½Π° Π³ΡΠ΅ΡΠΊΠ° ΠΈ ΠΈΠ΄Π΅ΡΡΠ° Π±Π΅ΡΠ΅ Π΄Π° ΡΠ΅ ΠΏΡΠΎΠ²Π΅ΡΡΡ ΠΈ Π΄Π²Π°ΡΠ° Π²Ρ ΠΎΠ΄Π½ΠΈ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡΠ°.
ΠΡΠ°Π²ΠΈΠ»Π΅Π½ Π²Π°ΡΠΈΠ°Π½Ρ:
static u32 scePsmfSetPsmf(u32 psmfStruct, u32 psmfData) {
if (!Memory::IsValidAddress(psmfStruct) ||
!Memory::IsValidAddress(psmfData)) {
return hleReportError(ME, SCE_KERNEL_ERROR_ILLEGAL_ADDRESS, "bad address");
}
....
}
ΠΠ°Π±ΡΠ°Π²Π΅Π½Π° ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π°
extern void ud_translate_att(
int size = 0;
....
if (size == 8) {
ud_asmprintf(u, "b");
} else if (size == 16) {
ud_asmprintf(u, "w");
} else if (size == 64) {
ud_asmprintf(u, "q");
}
....
}
PVS-Studio ΠΏΡΠ΅Π΄ΡΠΏΡΠ΅ΠΆΠ΄Π΅Π½ΠΈΠ΅:
Π’Π°Π·ΠΈ Π³ΡΠ΅ΡΠΊΠ° ΡΠ΅ Π½Π°ΠΌΠΈΡΠ° Π² ΠΏΠ°ΠΏΠΊΠ°ΡΠ° Π²ΡΡΡ, ΡΠ°ΠΊΠ° ΡΠ΅ Π½Π΅ Π΅ ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΡΡΠΎ Π·Π° ΠΏΡΠΎΠ΅ΠΊΡΠ°, Π½ΠΎ Π³ΡΠ΅ΡΠΊΠ°ΡΠ° Π±Π΅ΡΠ΅ ΠΎΡΠΊΡΠΈΡΠ° ΠΏΡΠ΅Π΄ΠΈ Π΄Π° Ρ Π·Π°Π±Π΅Π»Π΅ΠΆΠ°, ΡΠ°ΠΊΠ° ΡΠ΅ ΡΠ΅ΡΠΈΡ Π΄Π° Ρ ΠΎΡΡΠ°Π²Ρ. Π ΠΊΡΠ°ΠΉΠ½Π° ΡΠΌΠ΅ΡΠΊΠ° ΡΠ°Π·ΠΈ ΡΡΠ°ΡΠΈΡ Π½Π΅ Π΅ Π·Π° ΠΏΡΠ΅Π³Π»Π΅Π΄ Π½Π° Π³ΡΠ΅ΡΠΊΠΈ, Π° Π·Π° ΠΈΠ½ΡΠ΅Π³ΡΠ°ΡΠΈΡ Ρ Travis CI ΠΈ Π½Π΅ Π΅ ΠΈΠ·Π²ΡΡΡΠ΅Π½Π° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ Π½Π° Π°Π½Π°Π»ΠΈΠ·Π°ΡΠΎΡΠ°.
ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ² ΡΠ°Π·ΠΌΠ΅Ρ ΡΠ΅ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠ° ΠΎΡ ΠΊΠΎΠ½ΡΡΠ°Π½ΡΠ°, Π½ΠΎ ΠΈΠ·ΠΎΠ±ΡΠΎ Π½Π΅ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π² ΠΊΠΎΠ΄Π°, ΡΠ°ΠΊ Π΄ΠΎ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠ° if, ΠΊΠΎΠ΅ΡΠΎ, ΡΠ°Π·Π±ΠΈΡΠ° ΡΠ΅, Π΄Π°Π²Π° ΡΠ°Π»ΡΠΈΠ² Π΄ΠΎΠΊΠ°ΡΠΎ ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π°ΠΌΠ΅ ΡΡΠ»ΠΎΠ²ΠΈΡΡΠ°, Π·Π°ΡΠΎΡΠΎ, ΠΊΠ°ΠΊΡΠΎ ΡΠΈ ΡΠΏΠΎΠΌΠ½ΡΠΌΠ΅, ΡΠ°Π·ΠΌΠ΅Ρ ΡΠ°Π²Π½ΠΎ Π½Π° Π½ΡΠ»Π°. ΠΠΎΡΠ»Π΅Π΄Π²Π°ΡΠΈΡΠ΅ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ ΡΡΡΠΎ Π½ΡΠΌΠ°Ρ ΡΠΌΠΈΡΡΠ».
ΠΡΠ΅Π²ΠΈΠ΄Π½ΠΎ Π°Π²ΡΠΎΡΡΡ Π½Π° ΠΊΠΎΠ΄ΠΎΠ²ΠΈΡ ΡΡΠ°Π³ΠΌΠ΅Π½Ρ Π΅ Π·Π°Π±ΡΠ°Π²ΠΈΠ» Π΄Π° ΠΏΡΠ΅Π·Π°ΠΏΠΈΡΠ΅ ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π°ΡΠ° ΡΠ°Π·ΠΌΠ΅Ρ ΠΏΡΠ΅Π΄ΠΈ ΡΠΎΠ²Π°.
Π‘ΠΏΠΈΡΠ°Π½Π΅
ΠΠ΅ΡΠΎΡΡΠ½ΠΎ ΡΡΠΊ ΡΠ΅ ΠΏΡΠΈΠΊΠ»ΡΡΠΈΠΌ Ρ Π³ΡΠ΅ΡΠΊΠΈΡΠ΅. Π¦Π΅Π»ΡΠ° Π½Π° ΡΠ°Π·ΠΈ ΡΡΠ°ΡΠΈΡ Π΅ Π΄Π° Π΄Π΅ΠΌΠΎΠ½ΡΡΡΠΈΡΠ° ΡΠ°Π±ΠΎΡΠ°ΡΠ° Π½Π° PVS-Studio ΡΡΠ²ΠΌΠ΅ΡΡΠ½ΠΎ Ρ Travis CI, Π° Π½Π΅ Π΄Π° Π°Π½Π°Π»ΠΈΠ·ΠΈΡΠ° ΠΏΡΠΎΠ΅ΠΊΡΠ° Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉ-Π·Π°Π΄ΡΠ»Π±ΠΎΡΠ΅Π½ΠΎ. ΠΠΊΠΎ ΠΈΡΠΊΠ°ΡΠ΅ ΠΏΠΎ-Π³ΠΎΠ»Π΅ΠΌΠΈ ΠΈ ΠΏΠΎ-ΠΊΡΠ°ΡΠΈΠ²ΠΈ Π³ΡΠ΅ΡΠΊΠΈ, Π²ΠΈΠ½Π°Π³ΠΈ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΈΠΌ ΡΠ΅ Π²ΡΠ·Ρ
ΠΈΡΠ°Π²Π°ΡΠ΅
ΠΠ°ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅
ΠΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ΡΠΎ Π½Π° ΡΠ΅Π± ΡΡΠ»ΡΠ³ΠΈ Π·Π° ΠΈΠ·Π³ΡΠ°ΠΆΠ΄Π°Π½Π΅ Π½Π° ΠΏΡΠΎΠ΅ΠΊΡΠΈ Π·Π°Π΅Π΄Π½ΠΎ Ρ ΠΏΡΠ°ΠΊΡΠΈΠΊΠ°ΡΠ° Π½Π° ΠΈΠ½ΠΊΡΠ΅ΠΌΠ΅Π½ΡΠ°Π»Π΅Π½ Π°Π½Π°Π»ΠΈΠ· Π²ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ²Π° Π΄Π° ΠΎΡΠΊΡΠΈΠ΅ΡΠ΅ ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΈ Π²Π΅Π΄Π½Π°Π³Π° ΡΠ»Π΅Π΄ ΡΠ»ΠΈΠ²Π°Π½Π΅ΡΠΎ Π½Π° ΠΊΠΎΠ΄. ΠΠ΄Π½Π° ΠΊΠΎΠΌΠΏΠΈΠ»Π°ΡΠΈΡ ΠΎΠ±Π°ΡΠ΅ ΠΌΠΎΠΆΠ΅ Π΄Π° Π½Π΅ Π΅ Π΄ΠΎΡΡΠ°ΡΡΡΠ½Π°, ΡΠ°ΠΊΠ° ΡΠ΅ Π½Π°ΡΡΡΠΎΠΉΠΊΠ°ΡΠ° Π½Π° ΡΠ΅ΡΡΠ²Π°Π½Π΅ Π·Π°Π΅Π΄Π½ΠΎ ΡΡΡ ΡΡΠ°ΡΠΈΡΠ΅Π½ Π°Π½Π°Π»ΠΈΠ· Π·Π½Π°ΡΠΈΡΠ΅Π»Π½ΠΎ ΡΠ΅ ΠΏΠΎΠ΄ΠΎΠ±ΡΠΈ ΠΊΠ°ΡΠ΅ΡΡΠ²ΠΎΡΠΎ Π½Π° ΠΊΠΎΠ΄Π°.
ΠΠΎΠ»Π΅Π·Π½ΠΈ Π²ΡΡΠ·ΠΊΠΈ
Π‘ΡΠ°ΡΡΠΈΡΠ°Π½Π΅ Π½Π° PVS-Studio Π½Π° Linux ΠΈ macOS Π‘ΡΠ°ΡΡΠΈΡΠ°Π½Π΅ Π½Π° PVS-Studio Π² Docker Travis CI ΠΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡ
ΠΠΊΠΎ ΠΈΡΠΊΠ°ΡΠ΅ Π΄Π° ΡΠΏΠΎΠ΄Π΅Π»ΠΈΡΠ΅ ΡΠ°Π·ΠΈ ΡΡΠ°ΡΠΈΡ Ρ Π°Π½Π³Π»ΠΎΠ³ΠΎΠ²ΠΎΡΡΡΠ° Π°ΡΠ΄ΠΈΡΠΎΡΠΈΡ, ΠΌΠΎΠ»Ρ, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΡΠ΅ Π²ΡΡΠ·ΠΊΠ°ΡΠ° Π·Π° ΠΏΡΠ΅Π²ΠΎΠ΄: ΠΠ°ΠΊΡΠΈΠΌ ΠΠ²ΡΠ³ΠΈΠ½ΡΠ΅Π².
ΠΠ·ΡΠΎΡΠ½ΠΈΠΊ: www.habr.com