PSP рдЧреЗрдо рдХрдВрд╕реЛрд▓ рдПрдореБрд▓реЗрдЯрд░ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЯреНрд░реИрд╡рд┐рд╕ CI рдореЗрдВ рдкреАрд╡реАрдПрд╕-рд╕реНрдЯреВрдбрд┐рдпреЛ рдХреИрд╕реЗ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ

PPSSPP

рдЯреНрд░реИрд╡рд┐рд╕ CI рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рдФрд░ рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд▓рд┐рдП рд╡рд┐рддрд░рд┐рдд рд╡реЗрдм рд╕реЗрд╡рд╛ рд╣реИ рдЬреЛ рдПрдХ рд╕реЛрд░реНрд╕ рдХреЛрдб рд╣реЛрд╕реНрдЯрд┐рдВрдЧ рд╕реЗрд╡рд╛ рдХреЗ рд░реВрдк рдореЗрдВ GitHub рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдЙрдкрд░реЛрдХреНрдд рд▓рд┐рдкрд┐рдпреЛрдВ рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд, рдЖрдк рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ, рд╡реНрдпрд╛рдкрдХ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рд╣рдо PPSSPP рдХреЛрдб рдХреЗ рдЙрджрд╛рд╣рд░рдг рджреНрд╡рд╛рд░рд╛ PVS-Studio рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЯреНрд░реИрд╡рд┐рд╕ CI рдХреА рд╕реНрдерд╛рдкрдирд╛ рдХрд░реЗрдВрдЧреЗред

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


рдЯреНрд░реИрд╡рд┐рд╕ CI рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рдмрдирд╛рдиреЗ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдПрдХ рд╡реЗрдм рд╕реЗрд╡рд╛ рд╣реИред рдпрд╣ рдЖрдорддреМрд░ рдкрд░ рдирд┐рд░рдВрддрд░ рдПрдХреАрдХрд░рдг рдХреЗ рдЕрднреНрдпрд╛рд╕ рдХреЗ рд╕рд╛рде рд╕рдВрдпреЛрдЬрди рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

PPSSPP PSP рдЧреЗрдо рдХрдВрд╕реЛрд▓ рдХрд╛ рдПрдХ рдПрдореБрд▓реЗрдЯрд░ рд╣реИред рдХрд╛рд░реНрдпрдХреНрд░рдо рд╕реЛрдиреА PSP рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХреА рдЧрдИ рдбрд┐рд╕реНрдХ рдХреА рдЫрд╡рд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд┐рд╕реА рднреА рдЧреЗрдо рдХреЗ рд▓реЙрдиреНрдЪ рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИред рдпрд╣ рдХрд╛рд░реНрдпрдХреНрд░рдо 1 рдирд╡рдВрдмрд░ 2012 рдХреЛ рдЬрд╛рд░реА рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред PPSSPP рдХреЛ GPL v2 рд▓рд╛рдЗрд╕реЗрдВрд╕ рдХреЗ рддрд╣рдд рд╡рд┐рддрд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдХреЛрдИ рднреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд╕реНрд░реЛрдд рдХреЛрдб рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░ рд╕рдХрддрд╛ рд╣реИред

рдкреАрд╡реАрдПрд╕-рд╕реНрдЯреВрдбрд┐рдпреЛ - рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛрдб рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдФрд░ рд╕рдВрднрд╛рд╡рд┐рдд рдХрдордЬреЛрд░рд┐рдпреЛрдВ рдХреА рдЦреЛрдЬ рдХреЗ рд▓рд┐рдП рд╕реНрдерд┐рд░ рдХреЛрдб рд╡рд┐рд╢реНрд▓реЗрд╖рдХред рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рд╣рдо рд╡рд┐рднрд┐рдиреНрди рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдбреЗрд╡рд▓рдкрд░ рдХреЗ рдХрдВрдкреНрдпреВрдЯрд░ рдкрд░ рд╕реНрдерд╛рдиреАрдп рд░реВрдк рд╕реЗ рдмрдЬрд╛рдп рдХреНрд▓рд╛рдЙрдб рдореЗрдВ рдкреАрд╡реАрдПрд╕-рд╕реНрдЯреВрдбрд┐рдпреЛ рд▓реЙрдиреНрдЪ рдХрд░реЗрдВрдЧреЗ рдФрд░ рдкреАрдкреАрдПрд╕рдПрд╕рдкреАрдкреА рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреА рдЦреЛрдЬ рдХрд░реЗрдВрдЧреЗред

рдЯреНрд░реИрд╡рд┐рд╕ рд╕реА рд╕реЗрдЯ рдЕрдк


рд╣рдореЗрдВ GitHub рдкрд░ рдПрдХ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА рдЬрд╣рд╛рдВ рд╣рдореЗрдВ рдЬрд┐рд╕ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рд╡рд╣ рд╕реНрдерд┐рдд рд╣реИ, рд╕рд╛рде рд╣реА рдкреАрд╡реАрдПрд╕-рд╕реНрдЯреВрдбрд┐рдпреЛ рдХреЗ рд▓рд┐рдП рдПрдХ рдХреБрдВрдЬреА (рдЖрдк рдУрдкрди рд╕реЛрд░реНрд╕ рдкреНрд░реЛрдЬреЗрдХреНрдЯреНрд╕ рдХреЗ рд▓рд┐рдП рдПрдХ рдЯреНрд░рд╛рдпрд▓ рдХреБрдВрдЬреА рдпрд╛ рдирд┐рд╢реБрд▓реНрдХ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ)ред

рдЪрд▓реЛ рдЯреНрд░реИрд╡рд┐рд╕ рд╕реАрдЖрдИ рд╕рд╛рдЗрдЯ рдкрд░ рдЬрд╛рдПрдВред GitHub рдЦрд╛рддреЗ рдХреА рд╕рд╣рд╛рдпрддрд╛ рд╕реЗ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдХреЗ рдмрд╛рдж рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреА рдПрдХ рд╕реВрдЪреА рд╣реЛрдЧреА:



рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдПрдХ PPSSPP рдХрд╛рдВрдЯрд╛ рдмрдирд╛рдпрд╛ред

рд╣рдо рдЙрд╕ рднрдВрдбрд╛рд░ рдХреЛ рд╕рдХреНрд░рд┐рдп рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рд╕реЗ рд╣рдо рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ:



рдлрд┐рд▓рд╣рд╛рд▓, рдЯреНрд░реИрд╡рд┐рд╕ рд╕реАрдЖрдИ рд╣рдорд╛рд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдирд┐рд░реНрджреЗрд╢ рдирд╣реАрдВ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП рдпрд╣ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХрд╛ рд╕рдордп рд╣реИред

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



рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА:

  • 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 

рдЯреНрд░реИрд╡рд┐рд╕ CI рдЖрдкрдХреЛ рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрди рдЬреАрд╡рди рдХреЗ рд╡рд┐рднрд┐рдиреНрди рдЪрд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреА рдЦреБрдж рдХреА рдХрдорд╛рдВрдб рдЬреЛрдбрд╝рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдкреИрдХреЗрдЬ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдкрд╣рд▓реЗ рд╕реЗ рд╕реНрдерд╛рдкрд┐рдд рдЕрдиреБрднрд╛рдЧ рдЪрд▓рддрд╛ рд╣реИред рдлрд┐рд░ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ , рдЬреЛ addons.apt рд╕реВрдЪреА рд╕реЗ рд╕рдВрдХреБрд▓ рдХреА рд╕реНрдерд╛рдкрдирд╛ рдХрд╛ рдЕрдиреБрд╕рд░рдг рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рд╣рдордиреЗ рдКрдкрд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдпрд╛ рд╣реИред рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рд╣реА рдирд┐рд░реНрдорд╛рдг рд╣реЛрддрд╛ рд╣реИред рдпрджрд┐ рд╕рдм рдХреБрдЫ рд╕рдлрд▓ рд░рд╣рд╛ рд╣реИ, рддреЛ рд╣рдо after_success рдореЗрдВ рдЖрддреЗ рд╣реИрдВ (рдпрд╣ рд╡рд╣ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдВ рд╣рдо рд╕реНрдереИрддрд┐рдХ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рд╢реБрд░реВ рдХрд░реЗрдВрдЧреЗ)ред рдпреЗ рд╡реЗ рд╕рднреА рдЪрд░рдг рдирд╣реАрдВ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдЖрдк рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрджрд┐ рдЖрдкрдХреЛ рдФрд░ рдЕрдзрд┐рдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдЯреНрд░реИрд╡рд┐рд╕ рд╕реАрдЖрдИ рдкрд░ рдкреНрд░рд▓реЗрдЦрди рдореЗрдВ рджреЗрдЦрдирд╛ рдЪрд╛рд╣рд┐рдПред

рдХрдорд╛рдВрдб рдкрдврд╝рдиреЗ рдХреА рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рд╕реНрдХреНрд░рд┐рдкреНрдЯ .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 

рдкреИрдХреЗрдЬреЛрдВ рдХреЛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдЪрд▓реЛ рд╕рдмрдореЙрдбреНрдпреВрд▓ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВред PPSSPPs рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдкрд╣рд▓рд╛ рдлрд╝рдВрдХреНрд╢рди .travis.sh рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ (рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ):

 travis_before_install() { git submodule update --init --recursive } 

рдЕрдм рд╣рдо рд╕реАрдзреЗ рдЯреНрд░реИрд╡рд┐рд╕ рд╕реАрдЖрдИ рдореЗрдВ рдкреАрд╡реАрдПрд╕-рд╕реНрдЯреВрдбрд┐рдпреЛ рдХреЗ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд▓реЙрдиреНрдЪ рдХреА рд╕реНрдерд╛рдкрдирд╛ рдХреЗ рд▓рд┐рдП рдЖрдП рд╣реИрдВред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдореЗрдВ рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдкреАрд╡реАрдПрд╕-рд╕реНрдЯреВрдбрд┐рдпреЛ рдкреИрдХреЗрдЬ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:

 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-studio рдкреИрдХреЗрдЬ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд▓рд┐рдмрд┐рдпреЛ-рд╕реЙрдХреЗрдЯ-рдПрд╕рдПрд╕рдПрд▓-рдкрд░реНрд▓ рдФрд░ рд▓рд┐рдмрдиреЗрдЯ-рдПрд╕рдПрд▓рд╡рд╛рдИ-рдкрд░реНрд▓ рдкреИрдХреЗрдЬ рднреА рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЙрдиреНрд╣реЗрдВ рдореЗрд▓ рджреНрд╡рд╛рд░рд╛ рдкрд░рд┐рдгрд╛рдо рднреЗрдЬрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрджрд┐ рдЖрдкрдиреЗ рд░рд┐рдкреЛрд░реНрдЯ рд╡рд┐рддрд░рдг рдХрд╛ рджреВрд╕рд░рд╛ рддрд░реАрдХрд╛ рдЪреБрдирд╛ рд╣реИ рддреЛ рд╡реЗ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИрдВред

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 рдХреЗ рд▓рд┐рдП рд╕рдВрдХрд▓рди рдХрдорд╛рдВрдб рдирд┐рд░реНрдпрд╛рдд рдзреНрд╡рдЬ рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рдПрдХ рд╕реНрдерд┐рд░ рдХреЛрдб рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдЖрдк рдЗрд╕реЗ " рд▓рд┐рдирдХреНрд╕ рдФрд░ рдореИрдХрдУрдПрд╕ рдореЗрдВ рдкреАрд╡реАрдПрд╕-рд╕реНрдЯреВрдбрд┐рдпреЛ рдХреИрд╕реЗ рд▓реЙрдиреНрдЪ рдХрд░реЗрдВ " рд▓реЗрдЦ рдореЗрдВ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред

рдпрджрд┐ рдирд┐рд░реНрдорд╛рдг рд╕рдлрд▓ рд░рд╣рд╛, рддреЛ рд╣рдореЗрдВ after_success рдорд┐рд▓реЗрдЧрд╛ рдЬрд╣рд╛рдВ рд╣рдо рд╕реНрдереИрддрд┐рдХ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдЪрд▓рд╛рдПрдВрдЧреЗ:

 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 mail@domain.com \ -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 

рдкрд╣рд▓реА рдкрдВрдХреНрддрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд╛рдо рд╕реЗ рд▓рд╛рдЗрд╕реЗрдВрд╕ рдлрд╝рд╛рдЗрд▓ рдЙрддреНрдкрдиреНрди рдХрд░рддреА рд╣реИ рдФрд░ рдХреБрдВрдЬреА рдЬрд┐рд╕реЗ рд╣рдордиреЗ рдЯреНрд░реИрд╡рд┐рд╕ CI рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рдХреЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдпрд╛ рдерд╛ред

рджреВрд╕рд░реА рдкрдВрдХреНрддрд┐ рд╕реАрдзреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рд╢реБрд░реВ рдХрд░рддреА рд╣реИред рдзреНрд╡рдЬ -j <N> рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдереНрд░реЗрдбреНрд╕ рдХреА рд╕рдВрдЦреНрдпрд╛ рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ, рдзреНрд╡рдЬ -l <рдлрд╝рд╛рдЗрд▓> рд▓рд╛рдЗрд╕реЗрдВрд╕ рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ, рдзреНрд╡рдЬ -o <рдлрд╝рд╛рдЗрд▓> рд▓реЙрдЧреНрд╕ рдХреЛ рдЖрдЙрдЯрдкреБрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдлрд╝рд╛рдЗрд▓ рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдкрд░реАрдХреНрд╖рдг рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдзреНрд╡рдЬ - рдЕрдХреНрд╖рдорддрд╛ - рдЕрдХреНрд╖рдорддрд╛ рдЬрд╛рдБрдЪрддрд╛ рд╣реИ , рдХреНрдпреЛрдВрдХрд┐ рдбрд┐рдлрд╝реЙрд▓реНрдЯ 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 mail@domain.com \ -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 

рд╕рдм рдХреБрдЫ рдареАрдХ рд╣реИ рдФрд░ рдореЗрдорд╕реЗрдЯ рдлрдВрдХреНрд╢рди рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд░реИрдо рдореЗрдВ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдбреЗрдЯрд╛ рдорд┐рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рдЕрднреА рддрдХ рдЦреБрд╢ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдЖрдЗрдП рдЕрдиреБрдХреВрд▓рди рдХреЗ рд╕рд╛рде рд░рд┐рд▓реАрдЬрд╝ рд╕рдВрд╕реНрдХрд░рдг рдХреА рдХреЛрдбрд╛рдВрддрд░рдХ рд╕реВрдЪреА рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:
 ; 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-Studio рдЪреЗрддрд╛рд╡рдиреА: V547 рдПрдХреНрд╕рдкреНрд░реЗрд╢рди 'leftvol> = 0' рд╣рдореЗрд╢рд╛ рд╕рддреНрдп рд╣реЛрддрд╛ рд╣реИред sceAudio.cpp 120

рдкрд╣рд▓реЗ рдХреЗ рд▓рд┐рдП рджреВрд╕рд░реА рд╢рд╛рдЦрд╛ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ ред рдХреЛрдб рдХреЛ рдХреЗрд╡рд▓ рддрднреА рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдЬрдм рд╕рднреА рд╕реНрдерд┐рддрд┐рдпрд╛рдВ рд╡рд╛рдорд╛рд╡рд░реНрдд> 0xFFFFF || rightvol> 0xFFFF || рд╡рд╛рдорд╡реЛрд▓ <реж || rightvol <0 рдЭреВрдареЗ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрдерди рдорд┐рд▓рддреЗ рд╣реИрдВ рдЬреЛ рдЕрдиреНрдп рд╢рд╛рдЦрд╛ рдХреЗ рд▓рд┐рдП рд╕рд╣реА рд╣реЛрдВрдЧреЗ: leftvol <= 0xFFFFF, rightvol <= 0xFFFFF, 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 рд╕рдорд╛рди рдЙрдк-рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпрд╛рдБ рд╣реИрдВ! рдореЗрдореЛрд░реА :: IsValidAddress (psmfData) 'рдмрд╛рдИрдВ рдУрд░ рдФрд░ рджрд╛рдИрдВ рдУрд░' || рдСрдкрд░реЗрдЯрд░ред scePsmf.cpp 703

рдЕрдЧрд░ рдЕрдВрджрд░ рдЬрд╛рдБрдЪ рд╣реЛ рддреЛ рдиреЛрдЯ рдХрд░реЗрдВред рдХреНрдпрд╛ рдпрд╣ рдЖрдкрдХреЛ рдЕрдЬреАрдм рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рд╣рдо рдЬрд╛рдБрдЪ рд░рд╣реЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ 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 рдЪреЗрддрд╛рд╡рдиреА: V547 рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ 'рдЖрдХрд╛рд░ == 8' рд╣рдореЗрд╢рд╛ рдЧрд▓рдд рд╣реИред syn-att.c 195

рдпрд╣ рддреНрд░реБрдЯрд┐ рдПрдХреНрд╕рдЯреНрд░реАрдо рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рд╕реНрдерд┐рдд рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдкрд░ рд▓рд╛рдЧреВ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ, рд▓реЗрдХрд┐рди рддреНрд░реБрдЯрд┐ рдореБрдЭреЗ рджреЗрдЦрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдорд┐рд▓реА рдереА, рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдЗрд╕реЗ рд░рдЦрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рдлрд┐рд░ рднреА, рдпрд╣ рд▓реЗрдЦ рддреНрд░реБрдЯрд┐ рд╕рдореАрдХреНрд╖рд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рд╣реИ, рдмрд▓реНрдХрд┐ рдЯреНрд░реИрд╡рд┐рд╕ рд╕реАрдЖрдИ рдХреЗ рд╕рд╛рде рдПрдХреАрдХрд░рдг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИ рдФрд░ рдХреЛрдИ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред

рдЖрдХрд╛рд░ рдЪрд░ рдХреЛ рдПрдХ рдирд┐рд░рдВрддрд░ рдХреЗ рд╕рд╛рде рдЖрд░рдВрднреАрдХреГрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреЛрдб рдореЗрдВ рдмрд┐рд▓реНрдХреБрд▓ рднреА рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдпрджрд┐ рдСрдкрд░реЗрдЯрд░ рдЬреЛ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рд╕реНрдерд┐рддрд┐ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреЗ рд╕рдордп рдЧрд▓рдд рдЬрд╛рдирдХрд╛рд░реА рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐, рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо рдпрд╛рдж рдХрд░рддреЗ рд╣реИрдВ, рдЖрдХрд╛рд░ рд╢реВрдиреНрдп рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИред рдмрд╛рдж рдХреЗ рдЪреЗрдХ рдХрд╛ рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИред

рдЬрд╛рд╣рд┐рд░ рд╣реИ, рдХреЛрдб рдЯреБрдХрдбрд╝рд╛ рдХреЗ рд▓реЗрдЦрдХ рдЙрд╕рд╕реЗ рдкрд╣рд▓реЗ рдЖрдХрд╛рд░ рдЪрд░ рдХреЛ рд▓рд┐рдЦрдирд╛ рднреВрд▓ рдЧрдпрд╛ред

рдмрдВрдж рдХрд░реЛ


рд╣рдо рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рд░реБрдХрдиреЗ рд╡рд╛рд▓реЗ рд╣реИрдВред рдЗрд╕ рд▓реЗрдЦ рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рдпрд╣ рджрд┐рдЦрд╛рдирд╛ рд╣реИ рдХрд┐ рдкреАрд╡реАрдПрд╕-рд╕реНрдЯреВрдбрд┐рдпреЛ рдЯреНрд░реИрд╡рд┐рд╕ рд╕реАрдЖрдИ рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрд╕ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХрд╛ рдпрдерд╛рд╕рдВрднрд╡ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рдмрдбрд╝реА рдФрд░ рдЕрдзрд┐рдХ рд╕реБрдВрджрд░ рддреНрд░реБрдЯрд┐рдпрд╛рдВ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЙрдиреНрд╣реЗрдВ рд╣рдореЗрд╢рд╛ рдпрд╣рд╛рдВ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ :)ред

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


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

рдЙрдкрдпреЛрдЧреА рд▓рд┐рдВрдХ


Source: https://habr.com/ru/post/hi464641/


All Articles