Una ex probatissimis missionibus in usu PVS-Studii analysris est eius integratio cum systematis CI. Et licet analysis PVS-Studii propositi ex quavis fere continua integratione systematis in paucis tantum praeceptis edificari possit, pergimus ad hunc processum etiam commodiorem reddere. PVS-Studium nunc habet subsidium convertendi analysris output in forma pro TeamCity - TeamCity Inspectionum Type. Videamus quomodo operatur.
Information about the software used
Information about the project under study
Conemur hanc functionem in exemplo practico - in explicatione openRCT2 ineamus.
tionibus
Ut tempus conserves, probabiliter processum institutionis omittitur et ab momento incipiam cum TeamCity server currentem in computatrum meum habebo. Necesse est nos ire ad: localhost: {portum specificatorum per processum institutionem} (me in casu, localhost:9090) et data licentia inire. Post introitum salutati erimus;
Click in deprimendo crea Project. Deinde, elige Manually et agris imple.
Post premere puga Createsalutamur per fenestram uncinis.
Sit scriptor click Configuratione crea constructum.
Imple in agris et click Create. Videmus fenestram quaerentem te ut versionis systematis imperium deligeres. Cum fontes iam localiter siti sunt, preme Skip.
Denique ad propositum proficiscamur occasus.
Gradus addamus coetui, ut hoc cliccum feceris: Aedificare gradus -> addere gradum constructum.
Hic eligimus:
- Cursor type -> Imperii Versus
- Run -> Custom Script
Cum analysin in compilatione project, conventus et analysis unus sit gradus, sic imple in campo Scriptor Custom:
Singula vestigia postea videbimus. Aliquam sit amet quam analysrem onerantem, consilium congregans, analysing, relatum et formatting quod tantum undecim lineas codicis capit.
Extremum illud, quod faciendum est, variabiles ambitus constituitur, quas aliquos modos delineavi ad eorum promptitudinem emendandam. Ad hoc pergamus; Parametri -> addere novam parametri et tres variabiles adde:
Omnes facere vos have ut premere puga Curre in angulo dextro. Dum consilium convenitur et resolvitur, de scripto dicam.
directe scriptum
Primum, necesse est ut novissimam PVS-Studii distributionem accipiamus. Hac utimur in sarcina Chocolatey procurator. Qui enim plura de hoc scire volunt, ibi respondet
choco install pvs-studio -y
Deinceps in CLMonitor project utilitates persequendas deducamus.
%CLmon% monitor –-attach
Tunc aedificabimus project in environment variabilis Mas est iter ad versionem MSBuild opus facere
%MSB% %ProjPath% /t:clean
%MSB% %ProjPath% /t:rebuild /p:configuration=release
%MSB% %ProjPath% /t:g2
%MSB% %ProjPath% /t:PublishPortable
Ingrediamur login et licentia clavem pro PVS-Studio:
%PVS-Studio_cmd% credentials --username %PVS_Name% --serialNumber %PVS_Key%
Postquam constructum completum est, CLMonitor iterum currite ad fasciculos praeprocessionales et analysin staticos generandos;
%CLmon% analyze -l "c:ptest.plog"
Deinde alia utilitate ex nostra distributione utemur. PlogConverter relationem a forma vexillum ad formam TeamCity-specificam convertit. Propter hoc, eam directe in fenestra aedificare poterimus.
%PlogConverter% "c:ptest.plog" --renderTypes=TeamCity -o "C:temp"
Ultimus gradus est referre quae formatae sint in stdoutubi a parser TeamCity delecta erit.
type "C:tempptest.plog_TeamCity.txt"
Scriptum codice plena:
choco install pvs-studio -y
%CLmon% monitor --attach
set platform=x64
%MSB% %ProjPath% /t:clean
%MSB% %ProjPath% /t:rebuild /p:configuration=release
%MSB% %ProjPath% /t:g2
%MSB% %ProjPath% /t:PublishPortable
%PVS-Studio_cmd% credentials --username %PVS_Name% --serialNumber %PVS_Key%
%CLmon% analyze -l "c:ptest.plog"
%PlogConverter% "c:ptest.plog" --renderTypes=TeamCity -o "C:temp"
type "C:tempptest.plog_TeamCity.txt"
Interim consilio et analysis rei feliciter peractae ad tab projects et fac ex eo.
Nunc lets click in Summa inspectionesire inspicere analyser fama:
Monitiones numerorum regulae diagnosticae glomerantur. Per codicem navigare, debes strepere in linea numerorum monitu. Clicking in signum interrogationis in angulo dextro dextro tibi novam tab cum documentis aperiet. Navigare etiam potes per codicem strepitando in linea numero cum analysi admonitione. Navigation a remotis computatrum potest cum usura SourceTreeRoot titulum. Omnis qui hunc modum operationis analystoris quaerit, se cum sectione respondente consuescere potest
Videre analyser scriptor eventus
Nunc quod fabricamus instruimus et configuramus, inspice aliquas interesting admonitiones quae in proposito inspicimus.
Monitum N1
Object* CreateObjectFromJson(....)
{
Object* result = nullptr;
....
result = CreateObject(entry);
....
if (readContext.WasError())
{
throw std::runtime_error("Object has errors");
}
....
}
Object* CreateObject(const rct_object_entry& entry)
{
Object* result;
switch (entry.GetType())
{
case OBJECT_TYPE_RIDE:
result = new RideObject(entry);
break;
case OBJECT_TYPE_SMALL_SCENERY:
result = new SmallSceneryObject(entry);
break;
case OBJECT_TYPE_LARGE_SCENERY:
result = new LargeSceneryObject(entry);
break;
....
default:
throw std::runtime_error("Invalid object type");
}
return result;
}
Animadvertit analyser errorem quod post memoriam in dynamically collocans CreateObjectcum exceptio fit, non purgatur memoria, et fit memoria perpluo.
Monitum N2
static uint64_t window_cheats_page_enabled_widgets[] =
{
MAIN_CHEAT_ENABLED_WIDGETS |
(1ULL << WIDX_NO_MONEY) |
(1ULL << WIDX_ADD_SET_MONEY_GROUP) |
(1ULL << WIDX_MONEY_SPINNER) |
(1ULL << WIDX_MONEY_SPINNER_INCREMENT) |
(1ULL << WIDX_MONEY_SPINNER_DECREMENT) |
(1ULL << WIDX_ADD_MONEY) |
(1ULL << WIDX_SET_MONEY) |
(1ULL << WIDX_CLEAR_LOAN) |
(1ULL << WIDX_DATE_SET) |
(1ULL << WIDX_MONTH_BOX) | // <=
(1ULL << WIDX_MONTH_UP) |
(1ULL << WIDX_MONTH_DOWN) |
(1ULL << WIDX_YEAR_BOX) |
(1ULL << WIDX_YEAR_UP) |
(1ULL << WIDX_YEAR_DOWN) |
(1ULL << WIDX_DAY_BOX) |
(1ULL << WIDX_DAY_UP) |
(1ULL << WIDX_DAY_DOWN) |
(1ULL << WIDX_MONTH_BOX) | // <=
(1ULL << WIDX_DATE_GROUP) |
(1ULL << WIDX_DATE_RESET),
....
};
Pauci homines praeter static analysrem hanc diligentiam experiendi possent transire. Hoc exemplum crustulum bonum hac ratione caret.
Admonitiones N3
struct RCT12SpriteBase
{
....
uint8_t flags;
....
};
struct rct1_peep : RCT12SpriteBase
{
....
uint8_t flags;
....
};
Utique variabilis cum eodem nomine in basi classe et abneptis non semper est error. Attamen ipsa technica hereditas ponit omnes agros ordinis parentis in infantis genere adesse. Agros eodem nomine in heredem declarando confusionem facimus.
Monitum N4
void vehicle_visual_observation_tower(...., int32_t imageDirection, ....)
{
if ((imageDirection / 8) && (imageDirection / 8) != 3)
{
....
}
....
}
Propius inspiciamus. Expressio imageDirection/8 erit falsum, si imageDirection est in latitudine ab -7 ad 7. Secundae; (imageDirection / 8) != 3 checks imageDirection extra ordinem esse: a -31 ad -24 et a 24 ad 31 respective. Mihi admodum mirum videtur numeros pro inclusione quodam modo hoc modo cohibere et, etiamsi error in hoc codice non sit, has condiciones explicandas magis rescribendas commendem. Hoc multo facilius vitam faceret hominibus qui hunc codicem legerent et conservarent.
Monitum N5
void process_mouse_over(....)
{
....
switch (window->widgets[widgetId].type)
{
case WWT_VIEWPORT:
ebx = 0;
edi = cursorId; // <=
// Window event WE_UNKNOWN_0E was called here,
// but no windows actually implemented a handler and
// it's not known what it was for
cursorId = edi; // <=
if ((ebx & 0xFF) != 0)
{
set_cursor(cursorId);
return;
}
break;
....
}
....
}
Hoc fragmentum codicis verisimillimum est per compilationem. Deinde, relicta commento diiudicando, pars codicis non operantis sublata est. Sed adhuc duae operationes supersunt cursorIdquod etiam non multum sensum faciunt.
Monitum N6
void Network::ProcessPlayerList()
{
....
auto* player = GetPlayerByID(pendingPlayer.Id);
if (player == nullptr)
{
// Add new player.
player = AddPlayer("", "");
if (player) // <=
{
*player = pendingPlayer;
if (player->Flags & NETWORK_PLAYER_FLAG_ISSERVER)
{
_serverConnection->Player = player;
}
}
newPlayers.push_back(player->Id); // <=
}
....
}
Ex hoc codice satis facile est ad emendandum: vos iustus tertio tempore reprehendo ludius nulli monstratori, vel conditionali corpori add. Secundam optionem suggero;
void Network::ProcessPlayerList()
{
....
auto* player = GetPlayerByID(pendingPlayer.Id);
if (player == nullptr)
{
// Add new player.
player = AddPlayer("", "");
if (player)
{
*player = pendingPlayer;
if (player->Flags & NETWORK_PLAYER_FLAG_ISSERVER)
{
_serverConnection->Player = player;
}
newPlayers.push_back(player->Id);
}
}
....
}
Monitum N7
std::optional<ServerListEntry> ServerListEntry::FromJson(...)
{
auto name = json_object_get(server, "name");
.....
if (name == nullptr || version == nullptr)
{
....
}
else
{
....
entry.name = (name == nullptr ? "" : json_string_value(name));
....
}
....
}
Potes depellere durum-ad-read lineam codicis in uno lapsu decidit et problema solvendi pro reprimendo nullptr. Mutanda in codice hoc suadeant sic:
std::optional<ServerListEntry> ServerListEntry::FromJson(...)
{
auto name = json_object_get(server, "name");
.....
if (name == nullptr || version == nullptr)
{
name = ""
....
}
else
{
....
entry.name = json_string_value(name);
....
}
....
}
Monitum N8
void CustomListView::MouseUp(....)
{
....
if (!ColumnHeaderPressedCurrentState)
{
ColumnHeaderPressed = std::nullopt;
ColumnHeaderPressedCurrentState = false;
Invalidate();
}
}
Codicem satis mirum viderit. Mihi videtur typo vel in conditione vel cum re- variabili assignando ColumnHeaderPressedCurrentState idest falsum,.
conclusio,
Ut perspicimus, integrationem PVS-Studii static analysris in TeamCity vestram project admodum simplex est. Ad hoc faciendum, satis est unum fasciculum parvam configurationem scribere. Reperiens codicem sinet te cognoscere problemata statim post conventum, quae adiuvabit eas tollere, cum multiplicitas et sumptus mutationum adhuc iacent.
Si hunc articulum communicare cum auditorio Anglico loquentem vis, sis utere nexus translationis: Vladislav Stolyarov.
Source: www.habr.com