рдкреАрдПрд╕рдкреА рдЧреЗрдо рдХрдиреНрд╕реЛрд▓ рдПрдореБрд▓реЗрдЯрд░рдЪреЗ рдЙрджрд╛рд╣рд░рдг рд╡рд╛рдкрд░реВрди рдЯреНрд░реЕрд╡реНрд╣рд┐рд╕ рд╕реАрдЖрдпрдордзреНрдпреЗ рдкреАрд╡реНрд╣реАрдПрд╕-рд╕реНрдЯреБрдбрд┐рдУ рдХрд╕реЗ рдХреЙрдиреНрдлрд┐рдЧрд░ рдХрд░рд╛рд╡реЗ

рдкреАрдПрд╕рдкреА рдЧреЗрдо рдХрдиреНрд╕реЛрд▓ рдПрдореБрд▓реЗрдЯрд░рдЪреЗ рдЙрджрд╛рд╣рд░рдг рд╡рд╛рдкрд░реВрди рдЯреНрд░реЕрд╡реНрд╣рд┐рд╕ рд╕реАрдЖрдпрдордзреНрдпреЗ рдкреАрд╡реНрд╣реАрдПрд╕-рд╕реНрдЯреБрдбрд┐рдУ рдХрд╕реЗ рдХреЙрдиреНрдлрд┐рдЧрд░ рдХрд░рд╛рд╡реЗ
рдЯреНрд░реЕрд╡реНрд╣рд┐рд╕ рд╕реАрдЖрдп рд╣реА рд╕реЙрдлреНрдЯрд╡реЗрдЕрд░ рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдЖрдгрд┐ рдЪрд╛рдЪрдгреА рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдПрдХ рд╡рд┐рддрд░рд┐рдд рд╡реЗрдм рд╕реЗрд╡рд╛ рдЖрд╣реЗ рдЬреА GitHub рд▓рд╛ рд╕реНрддреНрд░реЛрдд рдХреЛрдб рд╣реЛрд╕реНрдЯрд┐рдВрдЧ рдореНрд╣рдгреВрди рд╡рд╛рдкрд░рддреЗ. рд╡рд░реАрд▓ рдСрдкрд░реЗрдЯрд┐рдВрдЧ рдкрд░рд┐рд╕реНрдерд┐рддреАрдВрд╡реНрдпрддрд┐рд░рд┐рдХреНрдд, рдЖрдкрдг рд╡рд┐рд╕реНрддреГрдд рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рдкрд░реНрдпрд╛рдпрд╛рдВрд╕рд╛рдареА рдЖрдкрд▓реЗ рд╕реНрд╡рддрдГрдЪреЗ рдзрдиреНрдпрд╡рд╛рдж рдЬреЛрдбреВ рд╢рдХрддрд╛. рдпрд╛ рд▓реЗрдЦрд╛рдд рдЖрдореНрд╣реА PPSSPP рдХреЛрдб рдЙрджрд╛рд╣рд░рдг рд╡рд╛рдкрд░реВрди PVS-Studio рд╕рд╣ рдХрд╛рдо рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА Travis CI рдХреЙрдиреНрдлрд┐рдЧрд░ рдХрд░реВ.

рдкрд░рд┐рдЪрдп

рдЯреНрд░реЗрд╡рд┐рд╕ рд╕реАрдЖрдп рд╕реЙрдлреНрдЯрд╡реЗрдЕрд░ рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдЖрдгрд┐ рдЪрд╛рдЪрдгреА рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдПрдХ рд╡реЗрдм рд╕реЗрд╡рд╛ рдЖрд╣реЗ. рд╣реЗ рд╕рд╣рд╕рд╛ рд╕рддрдд рдПрдХрддреНрд░реАрдХрд░рдг рдкрджреНрдзрддреАрдВрдЪреНрдпрд╛ рд╕рдВрдпреЛрдЧрд╛рдиреЗ рд╡рд╛рдкрд░рд▓реЗ рдЬрд╛рддреЗ.

рдкреАрдкреАрдПрд╕рдПрд╕рдкреАрдкреА - PSP рдЧреЗрдо рдХрдиреНрд╕реЛрд▓ рдПрдореБрд▓реЗрдЯрд░. рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╕реЛрдиреА рдкреАрдПрд╕рдкреАрд╕рд╛рдареА рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рдбрд┐рд╕реНрдХ рдкреНрд░рддрд┐рдорд╛рдВрдордзреВрди рдХреЛрдгрддреНрдпрд╛рд╣реА рдЧреЗрдордЪреНрдпрд╛ рд▓реЙрдиреНрдЪрдЪреЗ рдЕрдиреБрдХрд░рдг рдХрд░рдгреНрдпрд╛рд╕ рд╕рдХреНрд╖рдо рдЖрд╣реЗ. рд╣рд╛ рдХрд╛рд░реНрдпрдХреНрд░рдо 1 рдиреЛрд╡реНрд╣реЗрдВрдмрд░ 2012 рд░реЛрдЬреА рдкреНрд░рд╕рд┐рджреНрдз рдЭрд╛рд▓рд╛. PPSSPP рд╣рд╛ GPL v2 рдЕрдВрддрд░реНрдЧрдд рдкрд░рд╡рд╛рдирд╛рдХреГрдд рдЖрд╣реЗ. рдпрд╛рдордзреНрдпреЗ рдХреЛрдгреАрд╣реА рд╕реБрдзрд╛рд░рдгрд╛ рдХрд░реВ рд╢рдХрддреЛ рдкреНрд░рдХрд▓реНрдк рд╕реНрддреНрд░реЛрдд рдХреЛрдб.

рдкреАрд╡реНрд╣реАрдПрд╕-рд╕реНрдЯреБрдбрд┐рдУ - рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛрдбрдордзреАрд▓ рддреНрд░реБрдЯреА рдЖрдгрд┐ рд╕рдВрднрд╛рд╡реНрдп рднреЗрджреНрдпрддрд╛ рд╢реЛрдзрдгреНрдпрд╛рд╕рд╛рдареА рдПрдХ рд╕реНрдерд┐рд░ рдХреЛрдб рд╡рд┐рд╢реНрд▓реЗрд╖рдХ. рдпрд╛ рд▓реЗрдЦрд╛рдд, рдмрджрд▓рд╛рд╕рд╛рдареА, рдЖрдореНрд╣реА PVS-Studio рд▓рд╛ рдбреЗрд╡реНрд╣рд▓рдкрд░рдЪреНрдпрд╛ рдорд╢реАрдирд╡рд░ рдирд╛рд╣реА рддрд░ рдХреНрд▓рд╛рдЙрдбрдордзреНрдпреЗ рд▓реЙрдиреНрдЪ рдХрд░реВ рдЖрдгрд┐ PPSSPP рдордзреАрд▓ рддреНрд░реБрдЯреА рд╢реЛрдзреВ.

рдЯреНрд░реЕрд╡реНрд╣рд┐рд╕ рд╕реАрдЖрдп рд╕реЗрдЯ рдХрд░рдд рдЖрд╣реЗ

рдЖрдореНрд╣рд╛рд▓рд╛ GitHub рд╡рд░ рдПрдХ рднрд╛рдВрдбрд╛рд░ рд▓рд╛рдЧреЗрд▓, рдЬрд┐рдереЗ рдЖрдореНрд╣рд╛рд▓рд╛ рдЖрд╡рд╢реНрдпрдХ рдЕрд╕рд▓реЗрд▓рд╛ рдкреНрд░рдХрд▓реНрдк рдЖрд╣реЗ, рддрд╕реЗрдЪ PVS-Studio рд╕рд╛рдареА рдПрдХ рдХреА (рддреБрдореНрд╣реА рдорд┐рд│рд╡реВ рд╢рдХрддрд╛) рдЪрд╛рдЪрдгреА рдХреА рдХрд┐рдВрд╡рд╛ рдореБрдХреНрдд рд╕реНрд░реЛрдд рдкреНрд░рдХрд▓реНрдкрд╛рдВрд╕рд╛рдареА рд╡рд┐рдирд╛рдореВрд▓реНрдп).

рдЪрд▓рд╛ рд╕рд╛рдЗрдЯрд╡рд░ рдЬрд╛рдКрдпрд╛ рдЯреНрд░реЗрд╡рд┐рд╕ рд╕реАрдЖрдп. рддреБрдордЪреЗ GitHub рдЦрд╛рддреЗ рд╡рд╛рдкрд░реВрди рдЕрдзрд┐рдХреГрдд рдХреЗрд▓реНрдпрд╛рдирдВрддрд░, рдЖрдореНрд╣реА рднрд╛рдВрдбрд╛рд░рд╛рдВрдЪреА рд╕реВрдЪреА рдкрд╛рд╣реВ:

рдкреАрдПрд╕рдкреА рдЧреЗрдо рдХрдиреНрд╕реЛрд▓ рдПрдореБрд▓реЗрдЯрд░рдЪреЗ рдЙрджрд╛рд╣рд░рдг рд╡рд╛рдкрд░реВрди рдЯреНрд░реЕрд╡реНрд╣рд┐рд╕ рд╕реАрдЖрдпрдордзреНрдпреЗ рдкреАрд╡реНрд╣реАрдПрд╕-рд╕реНрдЯреБрдбрд┐рдУ рдХрд╕реЗ рдХреЙрдиреНрдлрд┐рдЧрд░ рдХрд░рд╛рд╡реЗ
рдЪрд╛рдЪрдгреАрд╕рд╛рдареА, рдореА PPSSPP рдлреЛрд░реНрдХ рдХреЗрд▓рд╛.

рдЖрдореНрд╣реА рд╕рдВрдЧреНрд░рд╣рд┐рдд рдХрд░реВ рдЗрдЪреНрдЫрд┐рдд рд░реЗрдкреЙрдЬрд┐рдЯрд░реА рд╕рдХреНрд░рд┐рдп рдХрд░рддреЛ:

рдкреАрдПрд╕рдкреА рдЧреЗрдо рдХрдиреНрд╕реЛрд▓ рдПрдореБрд▓реЗрдЯрд░рдЪреЗ рдЙрджрд╛рд╣рд░рдг рд╡рд╛рдкрд░реВрди рдЯреНрд░реЕрд╡реНрд╣рд┐рд╕ рд╕реАрдЖрдпрдордзреНрдпреЗ рдкреАрд╡реНрд╣реАрдПрд╕-рд╕реНрдЯреБрдбрд┐рдУ рдХрд╕реЗ рдХреЙрдиреНрдлрд┐рдЧрд░ рдХрд░рд╛рд╡реЗ
рдпрд╛ рдХреНрд╖рдгреА, рдЯреНрд░реЕрд╡реНрд╣рд┐рд╕ рд╕реАрдЖрдп рдЖрдордЪрд╛ рдкреНрд░рдХрд▓реНрдк рдмрд╛рдВрдзреВ рд╢рдХрдд рдирд╛рд╣реА рдХрд╛рд░рдг рдЗрдорд╛рд░рддреАрдЪреНрдпрд╛ рдХреЛрдгрддреНрдпрд╛рд╣реА рд╕реВрдЪрдирд╛ рдирд╛рд╣реАрдд. рддреНрдпрд╛рдореБрд│реЗ рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рдирдЪреА рд╡реЗрд│ рдЖрд▓реА рдЖрд╣реЗ.

рд╡рд┐рд╢реНрд▓реЗрд╖рдгрд╛рджрд░рдореНрдпрд╛рди, рдХрд╛рд╣реА рд╡реНрд╣реЗрд░рд┐рдПрдмрд▓реНрд╕ рдЖрдордЪреНрдпрд╛рд╕рд╛рдареА рдЙрдкрдпреБрдХреНрдд рдЕрд╕рддреАрд▓, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, PVS-Studio рдЪреА рдХреА, рдЬреА рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рдлрд╛рдЗрд▓рдордзреНрдпреЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдгреЗ рдЕрд╡рд╛рдВрдЫрд┐рдд рдЕрд╕реЗрд▓. рддрд░ рдЯреНрд░реЕрд╡реНрд╣рд┐рд╕ рд╕реАрдЖрдп рдордзреАрд▓ рдмрд┐рд▓реНрдб рд╕реЗрдЯрд┐рдВрдЧреНрдЬ рд╡рд╛рдкрд░реВрди рдкрд░реНрдпрд╛рд╡рд░рдг рд╡реНрд╣реЗрд░рд┐рдПрдмрд▓реНрд╕ рдЬреЛрдбреВрдпрд╛:

рдкреАрдПрд╕рдкреА рдЧреЗрдо рдХрдиреНрд╕реЛрд▓ рдПрдореБрд▓реЗрдЯрд░рдЪреЗ рдЙрджрд╛рд╣рд░рдг рд╡рд╛рдкрд░реВрди рдЯреНрд░реЕрд╡реНрд╣рд┐рд╕ рд╕реАрдЖрдпрдордзреНрдпреЗ рдкреАрд╡реНрд╣реАрдПрд╕-рд╕реНрдЯреБрдбрд┐рдУ рдХрд╕реЗ рдХреЙрдиреНрдлрд┐рдЧрд░ рдХрд░рд╛рд╡реЗ
рдЖрдореНрд╣рд╛рд▓рд╛ рдЖрд╡рд╢реНрдпрдХ рдЕрд╕реЗрд▓рдГ

  • PVS_USERNAME - рд╡рд╛рдкрд░рдХрд░реНрддрд╛рдирд╛рд╡
  • PVS_KEY - рдХреА
  • MAIL_USER - рдИрдореЗрд▓ рдЬреЛ рдЕрд╣рд╡рд╛рд▓ рдкрд╛рдард╡рдгреНрдпрд╛рд╕рд╛рдареА рд╡рд╛рдкрд░рд▓рд╛ рдЬрд╛рдИрд▓
  • MAIL_PASSWORD - рдИрдореЗрд▓ рдкрд╛рд╕рд╡рд░реНрдб

рд╢реЗрд╡рдЯрдЪреЗ рджреЛрди рдРрдЪреНрдЫрд┐рдХ рдЖрд╣реЗрдд. рд╣реЗ рдореЗрд▓рджреНрд╡рд╛рд░реЗ рдирд┐рдХрд╛рд▓ рдкрд╛рдард╡рдгреНрдпрд╛рд╕рд╛рдареА рд╡рд╛рдкрд░рд▓реЗ рдЬрд╛рддреАрд▓. рдЬрд░ рддреБрдореНрд╣рд╛рд▓рд╛ рдЕрд╣рд╡рд╛рд▓ рджреБрд╕рд░реНтАНрдпрд╛ рдорд╛рд░реНрдЧрд╛рдиреЗ рд╡рд┐рддрд░рд┐рдд рдХрд░рд╛рдпрдЪрд╛ рдЕрд╕реЗрд▓ рддрд░ рддреБрдореНрд╣рд╛рд▓рд╛ рддреЗ рд╕реВрдЪрд┐рдд рдХрд░рдгреНрдпрд╛рдЪреА рдЧрд░рдЬ рдирд╛рд╣реА.

рдореНрд╣рдгреВрди, рдЖрдореНрд╣рд╛рд▓рд╛ рдЖрд╡рд╢реНрдпрдХ рдЕрд╕рд▓реЗрд▓реЗ рдкрд░реНрдпрд╛рд╡рд░рдгреАрдп рдЪрд▓ рдЬреЛрдбрд▓реЗ рдЖрд╣реЗрдд:

рдкреАрдПрд╕рдкреА рдЧреЗрдо рдХрдиреНрд╕реЛрд▓ рдПрдореБрд▓реЗрдЯрд░рдЪреЗ рдЙрджрд╛рд╣рд░рдг рд╡рд╛рдкрд░реВрди рдЯреНрд░реЕрд╡реНрд╣рд┐рд╕ рд╕реАрдЖрдпрдордзреНрдпреЗ рдкреАрд╡реНрд╣реАрдПрд╕-рд╕реНрдЯреБрдбрд┐рдУ рдХрд╕реЗ рдХреЙрдиреНрдлрд┐рдЧрд░ рдХрд░рд╛рд╡реЗ
рдЖрддрд╛ рдПрдХ рдлрд╛рдИрд▓ рдмрдирд╡реВ .travis.yml рдЖрдгрд┐ рдкреНрд░рдХрд▓реНрдкрд╛рдЪреНрдпрд╛ рдореБрд│рд╛рд╢реА рдареЗрд╡рд╛. PPSSPP рдХрдбреЗ рдЯреНрд░реЕрд╡реНрд╣рд┐рд╕ CI рд╕рд╛рдареА рдЖрдзреАрдкрд╛рд╕реВрдирдЪ рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рдлрд╛рдЗрд▓ рд╣реЛрддреА, рддрдерд╛рдкрд┐, рддреА рдЦреВрдк рдореЛрдареА рд╣реЛрддреА рдЖрдгрд┐ рдЙрджрд╛рд╣рд░рдгрд╛рд╕рд╛рдареА рдкреВрд░реНрдгрдкрдгреЗ рдЕрдиреБрдкрдпреБрдХреНрдд рд╣реЛрддреА, рдореНрд╣рдгреВрди рдЖрдореНрд╣рд╛рд▓рд╛ рддреА рдореЛрдареНрдпрд╛ рдкреНрд░рдорд╛рдгрд╛рдд рд╕рд░рд▓реАрдХреГрдд рдХрд░рд╛рд╡реА рд▓рд╛рдЧрд▓реА рдЖрдгрд┐ рдлрдХреНрдд рдореВрд▓рднреВрдд рдШрдЯрдХ рд╕реЛрдбрд▓реЗ рдЧреЗрд▓реЗ.

рдкреНрд░рдердо, рдЖрдкрдг рд╡реНрд╣рд░реНрдЪреНрдпреБрдЕрд▓ рдорд╢реАрдирдордзреНрдпреЗ рд╡рд╛рдкрд░реВ рдЗрдЪреНрдЫрд┐рдд рдЕрд╕рд▓реЗрд▓реА рднрд╛рд╖рд╛, рдЙрдмрдВрдЯреВ рд▓рд┐рдирдХреНрд╕рдЪреА рдЖрд╡реГрддреНрддреА рдЖрдгрд┐ рдмрд┐рд▓реНрдбрд╕рд╛рдареА рдЖрд╡рд╢реНрдпрдХ рдкреЕрдХреЗрдЬреЗрд╕ рд╕реВрдЪрд┐рдд рдХрд░реВрдпрд╛:

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

рд╡рд┐рднрд╛рдЧрд╛рдмрджреНрджрд▓ рдереЛрдбреЗ рдЕрдзрд┐рдХ рдореЕрдЯреНрд░рд┐рдХреНрд╕. рдЯреНрд░реЕрд╡реНрд╣рд┐рд╕ 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

рдЯреНрд░реЕрд╡реНрд╣рд┐рд╕ рд╕реАрдЖрдп рддреБрдореНрд╣рд╛рд▓рд╛ рд╡реНрд╣рд░реНрдЪреНрдпреБрдЕрд▓ рдорд╢реАрдирдЪреНрдпрд╛ рдЖрдпреБрд╖реНрдпрд╛рддреАрд▓ рд╡рд┐рд╡рд┐рдз рдЯрдкреНрдкреНрдпрд╛рдВрд╕рд╛рдареА рддреБрдордЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ рдХрдорд╛рдВрдбреНрд╕ рдЬреЛрдбрдгреНрдпрд╛рдЪреА рдкрд░рд╡рд╛рдирдЧреА рджреЗрддреЗ. рд╡рд┐рднрд╛рдЧ рдЖрдзреА_рд╕реНрдерд╛рдкрд┐рдд рдХрд░рд╛ рдкреЕрдХреЗрдЬреЗрд╕ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдгреНрдпрд╛рдкреВрд░реНрд╡реА рдЕрдВрдорд▓рд╛рдд рдЖрдгрд▓реЗ. рдордЧ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рд╛, рдЬреЗ рд╕реВрдЪреАрдордзреВрди рдкреЕрдХреЗрдЬреЗрд╕рдЪреНрдпрд╛ рд╕реНрдерд╛рдкрдиреЗрдЪреЗ рдЕрдиреБрд╕рд░рдг рдХрд░рддреЗ 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
}

рдЖрддрд╛ рдЖрдореНрд╣реА 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 рд╕реНрдЯреЛрдЕрд░ рдореВрд▓реНрдп рд╣реЛрдп (рдЖрдореНрд╣реА рддреЗ рд╡рд┐рднрд╛рдЧрд╛рдд рд╕реВрдЪрд┐рдд рдХреЗрд▓реЗ рдЖрд╣реЗ env рдмрд┐рд▓реНрдб рдореЕрдЯреНрд░рд┐рдХреНрд╕ рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рджрд░рдореНрдпрд╛рди), рдЖрдореНрд╣реА рдкреЕрдХреЗрдЬ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЛ pvs-рд╕реНрдЯреБрдбрд┐рдУ. рдпрд╛ рд╡реНрдпрддрд┐рд░рд┐рдХреНрдд, рдкреЕрдХреЗрдЬреЗрд╕ рджреЗрдЦреАрд▓ рд╕реВрдЪрд┐рдд рдХреЗрд▓реЗ рдЖрд╣реЗрдд libio-рд╕реЙрдХреЗрдЯ-ssl-perl ╨╕ libnet-ssleay-perl, рддрдерд╛рдкрд┐, рддреЗ рдореЗрд▓рд┐рдВрдЧ рдкрд░рд┐рдгрд╛рдорд╛рдВрд╕рд╛рдареА рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗрдд, рдореНрд╣рдгреВрди рдЬрд░ рддреБрдореНрд╣реА рддреБрдордЪрд╛ рдЕрд╣рд╡рд╛рд▓ рд╡рд┐рддрд░рд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рджреБрд╕рд░реА рдкрджреНрдзрдд рдирд┐рд╡рдбрд▓реА рдЕрд╕реЗрд▓ рддрд░ рддреЗ рдЖрд╡рд╢реНрдпрдХ рдирд╛рд╣реАрдд.

рдХрд╛рд░реНрдп download_extract рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╕рдВрдЧреНрд░рд╣рдг рдбрд╛рдЙрдирд▓реЛрдб рдЖрдгрд┐ рдЕрдирдкреЕрдХ рдХрд░рддреЗ:

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 рд╕рдВрдХрд▓рди рдЖрджреЗрд╢ рдирд┐рд░реНрдпрд╛рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдзреНрд╡рдЬ. рд╕реНрдерд┐рд░ рдХреЛрдб рд╡рд┐рд╢реНрд▓реЗрд╖рдХрд╛рд╕рд╛рдареА рд╣реЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ. рдЖрдкрдг рд▓реЗрдЦрд╛рдд рдпрд╛рдмрджреНрджрд▓ рдЕрдзрд┐рдХ рд╡рд╛рдЪреВ рд╢рдХрддрд╛ "Linux рдЖрдгрд┐ macOS рд╡рд░ PVS-Studio рдХрд╕реЗ рдЪрд╛рд▓рд╡рд╛рдпрдЪреЗ".

рдЬрд░ рд╡рд┐рдзрд╛рдирд╕рднрд╛ рдпрд╢рд╕реНрд╡реА рдЭрд╛рд▓реА, рддрд░ рдЖрдореНрд╣рд╛рд▓рд╛ рдорд┐рд│реЗрд▓ рдпрд╢рд╛рдирдВрддрд░, рдЬреЗрдереЗ рдЖрдореНрд╣реА рд╕реНрдерд┐рд░ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рддреЛ:

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 рдкрд░реНрдпрд╛рд╡рд░рдг рд╡реНрд╣реЗрд░рд┐рдПрдмрд▓реНрд╕ рд╕реЗрдЯ рдХрд░рддрд╛рдирд╛ рдЕрдЧрджреА рд╕реБрд░реБрд╡рд╛рддреАрд▓рд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХреЗрд▓реА рд╣реЛрддреА.

рджреБрд╕рд░реА рдУрд│ рдереЗрдЯ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рд╕реБрд░реВ рдХрд░рддреЗ. рдЭреЗрдВрдбрд╛ -рдЬреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг, рдзреНрд╡рдЬрд╛рд╕рд╛рдареА рдереНрд░реЗрдбреНрд╕рдЪреА рд╕рдВрдЦреНрдпрд╛ рд╕реЗрдЯ рдХрд░рддреЗ -l рдкрд░рд╡рд╛рдирд╛, рдзреНрд╡рдЬ рд╕реВрдЪрд┐рдд рдХрд░рддреЗ -рдУ рд▓реЙрдЧ рдЖрдЙрдЯрдкреБрдЯ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдлрд╛рдЗрд▓ рдЖрдгрд┐ рдзреНрд╡рдЬ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ -рдЕрдХреНрд╖рдо рдкрд░рд╡рд╛рдирд╛ рд╕рдорд╛рдкреНрддреА рддрдкрд╛рд╕рдгреА рдбреАрдлреЙрд▓реНрдЯрдиреБрд╕рд╛рд░, рдЪрд╛рдЪрдгреА рдЖрд╡реГрддреНрддреНрдпрд╛рдВрд╕рд╛рдареА рдЖрд╡рд╢реНрдпрдХ pvs-рд╕реНрдЯреБрдбрд┐рдУ-рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рд╡рд╛рдкрд░рдХрд░реНрддреНрдпрд╛рд▓рд╛ рдЪреЗрддрд╛рд╡рдгреА рджреЗрдИрд▓ рдХреА рдкрд░рд╡рд╛рдирд╛ рдХрд╛рд▓рдмрд╛рд╣реНрдп рд╣реЛрдгрд╛рд░ рдЖрд╣реЗ. рд╣реЗ рд╣реЛрдгреНрдпрд╛рдкрд╛рд╕реВрди рд░реЛрдЦрдгреНрдпрд╛рд╕рд╛рдареА, рддреБрдореНрд╣реА рд╣рд╛ рдзреНрд╡рдЬ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реВ рд╢рдХрддрд╛.

рд▓реЙрдЧ рдлрд╛рдЗрд▓рдордзреНрдпреЗ рдХрдЪреНрдЪреЗ рдЖрдЙрдЯрдкреБрдЯ рдЖрд╣реЗ рдЬреЗ рд░реВрдкрд╛рдВрддрд░рдгрд╛рд╢рд┐рд╡рд╛рдп рд╡рд╛рдЪрд▓реЗ рдЬрд╛рдК рд╢рдХрдд рдирд╛рд╣реА, рдореНрд╣рдгреВрди рддреБрдореНрд╣реА рдкреНрд░рдердо рдлрд╛рдЗрд▓ рд╡рд╛рдЪрдиреАрдп рдмрдирд╡рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ. рдЪрд▓рд╛ рд▓реЙрдЧ рдкрд╛рд╕ рдХрд░реВрдпрд╛ 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;

рдЖрддрд╛ рдЧрд┐рдЯ рд░реЗрдкреЙрдЬрд┐рдЯрд░реАрдордзреНрдпреЗ рдмрджрд▓ рдкреБрд╢ рдХрд░рдгреНрдпрд╛рдЪреА рд╡реЗрд│ рдЖрд▓реА рдЖрд╣реЗ, рддреНрдпрд╛рдирдВрддрд░ рдЯреНрд░реЕрд╡реНрд╣рд┐рд╕ рд╕реАрдЖрдп рдЖрдкреЛрдЖрдк рдмрд┐рд▓реНрдб рдЪрд╛рд▓рд╡реЗрд▓. рдмрд┐рд▓реНрдб рд░рд┐рдкреЛрд░реНрдЯреНрд╕рд╡рд░ рдЬрд╛рдгреНрдпрд╛рд╕рд╛рдареА тАЬ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-рд╕реНрдЯреБрдбрд┐рдУ рдЪреЗрддрд╛рд╡рдгреА: V597 рдХрдВрдкрд╛рдЗрд▓рд░ 'рдореЗрдорд╕реЗрдЯ' рдлрдВрдХреНрд╢рди рдХреЙрд▓ рд╣рдЯрд╡реВ рд╢рдХрддреЛ, рдЬреЛ 'рд╕рдо' рдмрдлрд░ рдлреНрд▓рд╢ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рд╡рд╛рдкрд░рд▓рд╛ рдЬрд╛рддреЛ. RtlSecureZeroMemory() рдлрдВрдХреНрд╢рди рдЦрд╛рдЬрдЧреА рдбреЗрдЯрд╛ рдорд┐рдЯрд╡рдгреНрдпрд╛рд╕рд╛рдареА рд╡рд╛рдкрд░рд╛рд╡реЗ. sha1.cpp 325

рдХреЛрдбрдЪрд╛ рд╣рд╛ рддреБрдХрдбрд╛ рд╕реБрд░рдХреНрд╖рд┐рдд рд╣реЕрд╢рд┐рдВрдЧ рдореЙрдбреНрдпреВрд▓рдордзреНрдпреЗ рд╕реНрдерд┐рдд рдЖрд╣реЗ, рддрдерд╛рдкрд┐, рддреНрдпрд╛рдд рдПрдХ рдЧрдВрднреАрд░ рд╕реБрд░рдХреНрд╖рд╛ рддреНрд░реБрдЯреА рдЖрд╣реЗ (CWE-14). рдбреАрдмрдЧ рдЖрд╡реГрддреНрддреА рд╕рдВрдХрд▓рд┐рдд рдХрд░рддрд╛рдирд╛ рд╡реНрдпреБрддреНрдкрдиреНрди рдХреЗрд▓реЗрд▓реА рдЕрд╕реЗрдВрдмрд▓реА рд╕реВрдЪреА рдкрд╛рд╣реВрдпрд╛:

; Line 355
  mov r8d, 20
  xor edx, edx
  lea rcx, QWORD PTR sum$[rsp]
  call memset
; Line 356

рд╕рд░реНрд╡ рдХрд╛рд╣реА рдХреНрд░рдорд╛рдиреЗ рдЖрдгрд┐ рдХрд╛рд░реНрдп рдЖрд╣реЗ рдореЗрдорд╕реЗрдЯ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХреЗрд▓реЗ рдЬрд╛рддреЗ, рддреНрдпрд╛рджреНрд╡рд╛рд░реЗ RAM рдордзреАрд▓ рдорд╣рддреНрд╡рд╛рдЪрд╛ рдбреЗрдЯрд╛ рдЕрдзрд┐рд▓рд┐рдЦрд┐рдд рдХреЗрд▓рд╛ рдЬрд╛рддреЛ, рддрдерд╛рдкрд┐, рдЕрджреНрдпрд╛рдк рдЖрдирдВрджрд┐рдд рд╣реЛрдК рдирдХрд╛. рдСрдкреНрдЯрд┐рдорд╛рдпрдЭреЗрд╢рдирд╕рд╣ рд░рд┐рд▓реАрдЭ рдЖрд╡реГрддреНрддреАрдЪреА рдЕрд╕реЗрдВрдмрд▓реА рд╕реВрдЪреА рдкрд╛рд╣реВ:

; 354  :
; 355  :  memset( sum, 0, sizeof( sum ) );
; 356  :}

рд╕реВрдЪреАрдордзреВрди рдкрд╛рд╣рд┐рд▓реЗ рдЬрд╛рдК рд╢рдХрддреЗ, рдХрдВрдкрд╛рдЗрд▓рд░рдиреЗ рдХреЙрд▓рдХрдбреЗ рджреБрд░реНрд▓рдХреНрд╖ рдХреЗрд▓реЗ рдореЗрдорд╕реЗрдЯ. рд╣реЗ рдлрдВрдХреНрд╢рдирдордзреНрдпреЗ рдпрд╛ рд╡рд╕реНрддреБрд╕реНрдерд┐рддреАрдореБрд│реЗ рдЖрд╣реЗ sha1 рдХреЙрд▓ рдирдВрддрд░ рдореЗрдорд╕реЗрдЯ рд╕рдВрд░рдЪрдиреЗрдЪрд╛ рдЕрдзрд┐рдХ рд╕рдВрджрд░реНрдн рдирд╛рд╣реА рд╕реАрдЯреАрдПрдХреНрд╕. рддреНрдпрд╛рдореБрд│реЗ, рднрд╡рд┐рд╖реНрдпрд╛рдд рд╡рд╛рдкрд░рд▓реНрдпрд╛ рдЬрд╛рдгрд╛рд░реНтАНрдпрд╛ рдореЗрдорд░реА рдУрд╡реНрд╣рд░рд░рд╛рдИрдЯ рдХрд░рдгреНрдпрд╛рдд рдкреНрд░реЛрд╕реЗрд╕рд░рдЪрд╛ рд╡реЗрд│ рд╡рд╛рдпрд╛ рдШрд╛рд▓рд╡рдгреНрдпрд╛рдд рдХрдВрдкрд╛рдЗрд▓рд░рд▓рд╛ рдХрд╛рд╣реА рдЕрд░реНрде рдирд╛рд╣реА. рдлрдВрдХреНрд╢рди рд╡рд╛рдкрд░реВрди рддреБрдореНрд╣реА рдпрд╛рдЪреЗ рдирд┐рд░рд╛рдХрд░рдг рдХрд░реВ рд╢рдХрддрд╛ 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-рд╕реНрдЯреБрдбрд┐рдУ рдЪреЗрддрд╛рд╡рдгреА: V547 рдЕрднрд┐рд╡реНрдпрдХреНрддреА 'leftvol >= 0' рдиреЗрд╣рдореА рд╕рддреНрдп рдЕрд╕рддреЗ. sceAudio.cpp 120

рдкреНрд░рдердо рджреБрд╕рд▒реНрдпрд╛ рд╢рд╛рдЦреЗрдХрдбреЗ рд▓рдХреНрд╖ рджреНрдпрд╛ if. рд╕рд░реНрд╡ рдЕрдЯреА рдкреВрд░реНрдг рдХреЗрд▓реНрдпрд╛ рддрд░рдЪ рдХреЛрдб рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХреЗрд▓рд╛ рдЬрд╛рдИрд▓ leftvol > 0xFFFF || rightvol > 0xFFFF || рд▓реЗрдлреНрдЯрд╡реНрд╣реЛрд▓ < 0 || рд░рд╛рдЗрдЯрд╡реЙрд▓ < 0 рдЦреЛрдЯреЗ рдард░реЗрд▓. рдореНрд╣рдгреВрди, рдЖрдореНрд╣рд╛рд▓рд╛ рдЦрд╛рд▓реАрд▓ рд╡рд┐рдзрд╛рдиреЗ рдорд┐рд│рддрд╛рдд, рдЬреА рдЗрддрд░ рд╢рд╛рдЦреЗрд╕рд╛рдареА рд╕рддреНрдп рдЕрд╕рддреАрд▓: leftvol <= 0xFFFF, rightvol <= 0xFFFF, leftvol >= 0 ╨╕ rightvol >= 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");
  }
  ....
}

V501 '||' рдЪреНрдпрд╛ рдбрд╛рд╡реАрдХрдбреЗ рдЖрдгрд┐ рдЙрдЬрд╡реАрдХрдбреЗ '!Memory::IsValidAddress(psmfData)' рд╕рдорд╛рди рдЙрдк-рдЕрднрд┐рд╡реНрдпрдХреНрддреА рдЖрд╣реЗрдд. рдСрдкрд░реЗрдЯрд░ scePsmf.cpp 703

рдЖрдд рдЪреЗрдХрдХрдбреЗ рд▓рдХреНрд╖ рджреНрдпрд╛ if. рдкрддреНрддрд╛ рд╡реИрдз рдЖрд╣реЗ рдХреА рдирд╛рд╣реА рд╣реЗ рдЖрдореНрд╣реА рддрдкрд╛рд╕рдгреЗ рд╣реЗ рд╡рд┐рдЪрд┐рддреНрд░ рдЖрд╣реЗ рдЕрд╕реЗ рддреБрдореНрд╣рд╛рд▓рд╛ рд╡рд╛рдЯрдд рдирд╛рд╣реА рдХрд╛? psmf рдбреЗрдЯрд╛, рджреБрдкреНрдкрдЯ? рддреНрдпрд╛рдореБрд│реЗ рд╣реЗ рдорд▓рд╛ рд╡рд┐рдЪрд┐рддреНрд░ рд╡рд╛рдЯрддреЗ... рдЦрд░рдВ рддрд░, рд╣реЗ рдЕрд░реНрдерд╛рддрдЪ рдПрдХ рдЯрд╛рдпрдкреЛ рдЖрд╣реЗ, рдЖрдгрд┐ рджреЛрдиреНрд╣реА рдЗрдирдкреБрдЯ рдкреЕрд░рд╛рдореАрдЯрд░реНрд╕ рддрдкрд╛рд╕рдгреНрдпрд╛рдЪреА рдХрд▓реНрдкрдирд╛ рд╣реЛрддреА.

рдпреЛрдЧреНрдп рдкрд░реНрдпрд╛рдп:

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-рд╕реНрдЯреБрдбрд┐рдУ рдЪреЗрддрд╛рд╡рдгреА: V547 рдЕрднрд┐рд╡реНрдпрдХреНрддреА 'рдЖрдХрд╛рд░ == 8' рдиреЗрд╣рдореА рдЕрд╕рддреНрдп рдЕрд╕рддреЗ. syn-att.c 195

рд╣реА рддреНрд░реБрдЯреА рдлреЛрд▓реНрдбрд░рдордзреНрдпреЗ рдЖрд╣реЗ ext, рддреНрдпрд╛рдореБрд│реЗ рдкреНрд░рдХрд▓реНрдкрд╛рд╢реА рдЦрд░реЛрдЦрд░ рд╕рдВрдмрдВрдзрд┐рдд рдирд╛рд╣реА, рдкрд░рдВрддреБ рдмрдЧ рдорд╛рдЭреНрдпрд╛ рд▓рдХреНрд╖рд╛рдд рдпреЗрдгреНрдпрд╛рдкреВрд░реНрд╡реАрдЪ рд╕рд╛рдкрдбрд▓рд╛ рд╣реЛрддрд╛, рдореНрд╣рдгреВрди рдореА рддреЛ рд╕реЛрдбрдгреНрдпрд╛рдЪрд╛ рдирд┐рд░реНрдгрдп рдШреЗрддрд▓рд╛. рд╢реЗрд╡рдЯреА, рд╣рд╛ рд▓реЗрдЦ рддреНрд░реБрдЯреАрдВрдЪреЗ рдкреБрдирд░рд╛рд╡рд▓реЛрдХрди рдХрд░рдгреНрдпрд╛рдмрджреНрджрд▓ рдирд╛рд╣реА, рдкрд░рдВрддреБ рдЯреНрд░реЕрд╡реНрд╣рд┐рд╕ рд╕реАрдЖрдп рд╕рд╣ рдПрдХрддреНрд░реАрдХрд░рдгрд╛рдмрджреНрджрд▓ рдЖрд╣реЗ рдЖрдгрд┐ рд╡рд┐рд╢реНрд▓реЗрд╖рдХрд╛рдЪреЗ рдХреЛрдгрддреЗрд╣реА рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рдХреЗрд▓реЗ рдЧреЗрд▓реЗ рдирд╛рд╣реА.

рдЪрд▓ рдЖрдХрд╛рд░ рдПрдХрд╛ рд╕реНрдерд┐рд░рд╛рдВрдХрд╛рдиреЗ рдЖрд░рдВрдн рдХреЗрд▓рд╛ рдЬрд╛рддреЛ, рддрдерд╛рдкрд┐, рддреЛ рдХреЛрдбрдордзреНрдпреЗ рдЕрдЬрд┐рдмрд╛рдд рд╡рд╛рдкрд░рд▓рд╛ рдЬрд╛рдд рдирд╛рд╣реА, рдереЗрдЯ рдСрдкрд░реЗрдЯрд░рдкрд░реНрдпрдВрдд if, рдЬреЗ, рдЕрд░реНрдерд╛рддрдЪ, рджреЗрддреЗ рдЦреЛрдЯреЗ рдкрд░рд┐рд╕реНрдерд┐рддреА рддрдкрд╛рд╕рддрд╛рдирд╛, рдХрд╛рд░рдг, рдЬрд╕реЗ рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рдЖрдард╡рддреЗ, рдЖрдХрд╛рд░ рд╢реВрдиреНрдпрд╛рдЪреНрдпрд╛ рдмрд░реЛрдмрд░реАрдЪреЗ. рддреНрдпрд╛рдирдВрддрд░рдЪреНрдпрд╛ рддрдкрд╛рд╕рдгреНрдпрд╛рдВрдирд╛рд╣реА рдХрд╛рд╣реА рдЕрд░реНрде рдирд╛рд╣реА.

рд╡рд░рд╡рд░ рдкрд╛рд╣рддрд╛, рдХреЛрдб рдлреНрд░реЕрдЧрдореЗрдВрдЯрдЪрд╛ рд▓реЗрдЦрдХ рд╡реНрд╣реЗрд░рд┐рдПрдмрд▓ рдУрд╡реНрд╣рд░рд░рд╛рдИрдЯ рдХрд░рдгреНрдпрд╛рд╕ рд╡рд┐рд╕рд░рд▓рд╛ рдЖрдХрд╛рд░ рддреНрдпрд╛рдкреВрд░реНрд╡реА.

рдерд╛рдВрдмрд╛

рдЗрдереЗрдЪ рдЖрдкрдг рдХрджрд╛рдЪрд┐рдд рдЪреБрдХрд╛ рд╕рдВрдкрд╡реВ. рдпрд╛ рд▓реЗрдЦрд╛рдЪрд╛ рдЙрджреНрджреЗрд╢ PVS-Studio рдЪреЗ Travis CI рд╕рд╣ рдПрдХрддреНрд░рд┐рддрдкрдгреЗ рдХрд╛рдо рджрд╛рдЦрд╡рдгреЗ рдЖрдгрд┐ рдкреНрд░рдХрд▓реНрдкрд╛рдЪреЗ рд╢рдХреНрдп рддрд┐рддрдХреЗ рдкреВрд░реНрдг рд╡рд┐рд╢реНрд▓реЗрд╖рдг рди рдХрд░рдгреЗ рд╣рд╛ рдЖрд╣реЗ. рдЬрд░ рддреБрдореНрд╣рд╛рд▓рд╛ рдореЛрдареНрдпрд╛ рдЖрдгрд┐ рдЕрдзрд┐рдХ рд╕реБрдВрджрд░ рдЪреБрдХрд╛ рд╣рд╡реНрдпрд╛ рдЕрд╕рддреАрд▓ рддрд░ рддреБрдореНрд╣реА рддреНрдпрд╛рдВрдЪреА рдиреЗрд╣рдореА рдкреНрд░рд╢рдВрд╕рд╛ рдХрд░реВ рд╢рдХрддрд╛ рдпреЗрдереЗ :).

рдирд┐рд╖реНрдХрд░реНрд╖

рд╡рд╛рдвреАрд╡ рд╡рд┐рд╢реНрд▓реЗрд╖рдгрд╛рдЪреНрдпрд╛ рд╕рд░рд╛рд╡рд╛рд╕рд╣ рдкреНрд░рдХрд▓реНрдк рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рд╡реЗрдм рд╕реЗрд╡рд╛ рд╡рд╛рдкрд░рдгреЗ рдХреЛрдб рд╡рд┐рд▓реАрди рдХреЗрд▓реНрдпрд╛рдирдВрддрд░ рд▓рдЧреЗрдЪрдЪ рдЕрдиреЗрдХ рд╕рдорд╕реНрдпрд╛ рд╢реЛрдзреВ рджреЗрддреЗ. рддрдерд╛рдкрд┐, рдПрдХ рдмрд┐рд▓реНрдб рдкреБрд░реЗрд╕реЗ рдЕрд╕реВ рд╢рдХрдд рдирд╛рд╣реА, рдореНрд╣рдгреВрди рд╕реНрдерд┐рд░ рд╡рд┐рд╢реНрд▓реЗрд╖рдгрд╛рд╕рд╣ рдЪрд╛рдЪрдгреА рд╕реЗрдЯ рдХрд░рдгреЗ рдХреЛрдбрдЪреНрдпрд╛ рдЧреБрдгрд╡рддреНрддреЗрдд рд▓рдХреНрд╖рдгреАрдп рд╕реБрдзрд╛рд░рдгрд╛ рдХрд░реЗрд▓.

рдЙрдкрдпреБрдХреНрдд рджреБрд╡реЗ

рдкреАрдПрд╕рдкреА рдЧреЗрдо рдХрдиреНрд╕реЛрд▓ рдПрдореБрд▓реЗрдЯрд░рдЪреЗ рдЙрджрд╛рд╣рд░рдг рд╡рд╛рдкрд░реВрди рдЯреНрд░реЕрд╡реНрд╣рд┐рд╕ рд╕реАрдЖрдпрдордзреНрдпреЗ рдкреАрд╡реНрд╣реАрдПрд╕-рд╕реНрдЯреБрдбрд┐рдУ рдХрд╕реЗ рдХреЙрдиреНрдлрд┐рдЧрд░ рдХрд░рд╛рд╡реЗ

рдЬрд░ рддреБрдореНрд╣рд╛рд▓рд╛ рд╣рд╛ рд▓реЗрдЦ рдЗрдВрдЧреНрд░рдЬреА рднрд╛рд╖рд┐рдХ рдкреНрд░реЗрдХреНрд╖рдХрд╛рдВрд╕рд╣ рд╕рд╛рдорд╛рдпрд┐рдХ рдХрд░рд╛рдпрдЪрд╛ рдЕрд╕реЗрд▓ рддрд░ рдХреГрдкрдпрд╛ рднрд╛рд╖рд╛рдВрддрд░ рджреБрд╡рд╛ рд╡рд╛рдкрд░рд╛: Maxim Zvyagintsev. рдкреАрдПрд╕рдкреА рдЧреЗрдо рдХрдиреНрд╕реЛрд▓ рдПрдореБрд▓реЗрдЯрд░рдЪреЗ рдЙрджрд╛рд╣рд░рдг рд╡рд╛рдкрд░реВрди рдЯреНрд░реЕрд╡реНрд╣рд┐рд╕ рд╕реАрдЖрдпрдордзреНрдпреЗ рдкреАрд╡реНрд╣реАрдПрд╕-рд╕реНрдЯреБрдбрд┐рдУ рдХрд╕рд╛ рд╕реЗрдЯ рдХрд░рд╛рдпрдЪрд╛.

рд╕реНрддреНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЬреЛрдбрд╛