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

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

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

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

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

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

рдЯреНрд░реИрд╡рд┐рд╕ рд╕реАрдЖрдИ рдХреА рд╕реНрдерд╛рдкрдирд╛

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

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

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

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

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

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

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

  • PVS_USERNAME - рдЙрдкрдпреЛрдХреНрддрд╛рдирд╛рдо
  • PVS_KEY - рдХреБрдВрдЬреА
  • MAIL_USER - рдИрдореЗрд▓ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд░рд┐рдкреЛрд░реНрдЯ рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛
  • MAIL_PASSWORD - рдИрдореЗрд▓ рдкрд╛рд╕рд╡рд░реНрдб

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

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

рдкреАрдПрд╕рдкреА рдЧреЗрдо рдХрдВрд╕реЛрд▓ рдПрдореБрд▓реЗрдЯрд░ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЯреНрд░реИрд╡рд┐рд╕ рд╕реАрдЖрдИ рдореЗрдВ рдкреАрд╡реАрдПрд╕-рд╕реНрдЯреВрдбрд┐рдпреЛ рдХреЛ рдХреИрд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВ
рдЕрдм рдПрдХ рдлрд╛рдЗрд▓ рдмрдирд╛рддреЗ рд╣реИрдВ .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: PPSSPP_BUILD_TYPE=Linux PVS_ANALYZE=Yes
    - os: linux
      compiler: "clang"
      env: PPSSPP_BUILD_TYPE=Linux

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

рдЬреЛ рдХреБрдЫ рдмрдЪрд╛ рд╣реИ рд╡рд╣ рдкрд░рд┐рдпреЛрдЬрдирд╛-рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЕрд╕реЗрдВрдмрд▓реА рдирд┐рд░реНрджреЗрд╢ рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рд╣реИ:

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

рдкреИрдХреЗрдЬреЛрдВ рдХреЛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рд╕рдмрдореЙрдбреНрдпреВрд▓ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВрдЧреЗред рдкреАрдкреАрдПрд╕рдПрд╕рдкреАрдкреА рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЖрдЗрдП рдЗрд╕рдореЗрдВ рдкрд╣рд▓рд╛ рдлрд╝рдВрдХреНрд╢рди рдЬреЛрдбрд╝реЗрдВ .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
}

рд╕рдорд╛рд░реЛрд╣ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдЯреНрд░реИрд╡рд┐рд╕_рдЗрдВрд╕реНрдЯреЙрд▓ рд╣рдо рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЖрд╡рд╢реНрдпрдХ рдХрдВрдкрд╛рдЗрд▓рд░ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдлрд┐рд░ рдпрджрд┐ рд╡реЗрд░рд┐рдПрдмрд▓ $PVS_ANALYZE рдореВрд▓реНрдп рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ рд╣рд╛рдБ (рд╣рдордиреЗ рдЗрд╕реЗ рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рджрд░реНрд╢рд╛рдпрд╛ рд╣реИ env рдмрд┐рд▓реНрдб рдореИрдЯреНрд░рд┐рдХреНрд╕ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЗ рджреМрд░рд╛рди), рд╣рдо рдкреИрдХреЗрдЬ рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ рдкреАрд╡реАрдПрд╕-рд╕реНрдЯреВрдбрд┐рдпреЛ. рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдкреИрдХреЗрдЬ рднреА рдмрддрд╛рдП рдЧрдП рд╣реИрдВ рд▓рд┐рдмрд┐рдпреЛ-рд╕реЙрдХреЗрдЯ-рдПрд╕рдПрд╕рдПрд▓-рдкрд░реНрд▓ ╨╕ 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

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

рдпрджрд┐ рд╕рднрд╛ рд╕рдлрд▓ рд░рд╣реА, рддреЛ рд╣рдо рдкрд╣реБрдВрдЪреЗрдВрдЧреЗ рд╕рдлрд▓рддрд╛ рдХреЗ рдмрд╛рдж, рдЬрд╣рд╛рдВ рд╣рдо рд╕реНрдереИрддрд┐рдХ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рддреЗ рд╣реИрдВ:

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

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

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

рд▓реЙрдЧ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдХрдЪреНрдЪрд╛ рдЖрдЙрдЯрдкреБрдЯ рд╣реЛрддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рд░реВрдкрд╛рдВрддрд░рдг рдХреЗ рдмрд┐рдирд╛ рдирд╣реАрдВ рдкрдврд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рдкрд╣рд▓реЗ рдлрд╝рд╛рдЗрд▓ рдХреЛ рдкрдврд╝рдиреЗ рдпреЛрдЧреНрдп рдмрдирд╛рдирд╛ рд╣реЛрдЧрд╛ред рдЖрдЗрдП рд▓реЙрдЧ рдХреЛ рдкрд╛рд░ рдХрд░реЗрдВ рдкреНрд▓реЙрдЧ-рдХрдиреНрд╡рд░реНрдЯрд░, рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рдПрдХ 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 ) );
}

рдкреАрд╡реАрдПрд╕-рд╕реНрдЯреВрдбрд┐рдпреЛ рдЪреЗрддрд╛рд╡рдиреА: V597 рдХрдВрдкрд╛рдЗрд▓рд░ 'рдореЗрдорд╕реЗрдЯ' рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдХреЛ рд╣рдЯрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ 'рд╕рдо' рдмрдлрд░ рдХреЛ рдлреНрд▓рд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдирд┐рдЬреА рдбреЗрдЯрд╛ рдХреЛ рдорд┐рдЯрд╛рдиреЗ рдХреЗ рд▓рд┐рдП RtlSecureZeroMemory() рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред sha1.cpp 325

рдХреЛрдб рдХрд╛ рдпрд╣ рдЯреБрдХрдбрд╝рд╛ рд╕реБрд░рдХреНрд╖рд┐рдд рд╣реИрд╢рд┐рдВрдЧ рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рд╕реНрдерд┐рдд рд╣реИ, рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЗрд╕рдореЗрдВ рдПрдХ рдЧрдВрднреАрд░ рд╕реБрд░рдХреНрд╖рд╛ рджреЛрд╖ рд╣реИ (рд╕реАрдбрдмреНрд▓реНрдпреВрдИ-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);
  }
}

рдкреАрд╡реАрдПрд╕-рд╕реНрдЯреВрдбрд┐рдпреЛ рдЪреЗрддрд╛рд╡рдиреА: V547 рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ 'leftvol >= 0' рд╕рджреИрд╡ рд╕рддреНрдп рд╣реИред sceAudio.cpp 120

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдЕрдиреНрдп рд╢рд╛рдЦрд╛ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ if. рд╕рднреА рд╢рд░реНрддреЗрдВ рдкреВрд░реА рд╣реЛрдиреЗ рдкрд░ рд╣реА рдХреЛрдб рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рд▓реЗрдлреНрдЯрд╡реЙрд▓ > 0xFFFF || рд░рд╛рдЗрдЯрд╡реЙрд▓ > 0xFFFF || рд▓реЗрдлреНрдЯрд╡реЛрд▓ < 0 || рд░рд╛рдЗрдЯрд╡реЛрд▓ <0 рдЭреВрда рдирд┐рдХрд▓реЗрдЧрд╛. рдЗрд╕рд▓рд┐рдП, рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрдерди рдорд┐рд▓рддреЗ рд╣реИрдВ, рдЬреЛ рдЕрдиреНрдп рд╢рд╛рдЦрд╛ рдХреЗ рд▓рд┐рдП рд╕рддреНрдп рд╣реЛрдВрдЧреЗ: рд▓реЗрдлреНрдЯрд╡реЙрд▓ <= 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");
  }
  ....
}

V501 '||' рдХреЗ рдмрд╛рдИрдВ рдУрд░ рдФрд░ рджрд╛рдИрдВ рдУрд░ рд╕рдорд╛рди рдЙрдк-рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпрд╛рдБ '!Memory::IsValidAddress(psmfData)' рд╣реИрдВред рдСрдкрд░реЗрдЯрд░ред scePsmf.cpp 703

рдЕрдВрджрд░ рдХреА рдЬрд╛рдВрдЪ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ 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");
  }
  ....
}

рдкреАрд╡реАрдПрд╕-рд╕реНрдЯреВрдбрд┐рдпреЛ рдЪреЗрддрд╛рд╡рдиреА: V547 рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ 'рдЖрдХрд╛рд░ == 8' рд╕рджреИрд╡ рдЕрд╕рддреНрдп рд╣реИред syn-att.c 195

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

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

рдЬрд╛рд╣рд┐рд░ рд╣реИ, рдХреЛрдб рдЦрдВрдб рдХрд╛ рд▓реЗрдЦрдХ рд╡реЗрд░рд┐рдПрдмрд▓ рдХреЛ рдЕрдзрд┐рд▓реЗрдЦрд┐рдд рдХрд░рдирд╛ рднреВрд▓ рдЧрдпрд╛ рдЖрдХрд╛рд░ рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗред

рд░реБрдХреЗрдВ

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

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

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

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

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

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

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

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЬреЛрдбрд╝реЗрдВ