Development/Tutorials/Code Checking (pt BR)

From KDE TechBase
Revision as of 00:06, 20 January 2011 by Camilasan (talk | contribs)


Development/Tutorials/Code Checking


Code Checking

Há muitas maneiras de encontrar bugs no código do KDE. Cada vez mais, os desenvolvedores do KDE estão usando ferramentas automatizadas. Você pode usar algumas dessas ferramentas para melhorar o seu próprio código.

The KDE 'Krazy' Checker

Desenvolvedores do KDE tem um simples conjunto de testes que são conhecidos coletivamente como "Krazy". Esses testes foram desenvolvidos originalmente para ser executado como parte de um conjunto de testes em uma máquina conhecida como http://www.englishbreakfastnetwork.org, ou EBN. Você pode ver os resultados da execução de diversos testes noEBN (em http://www.englishbreakfastnetwork.org/krazy/).

Você também pode executar os testes de si mesmo. Para fazer isso, você precisa obter uma cópia do código krazy2/install.txt e instalá-los. Você pode testar um único arquivo (usando o aplicativo krazy2) ou uma árvore inteira, incluindo subdiretórios (usando o aplicativo krazy2all).

Como funciona o Krazy

The Krazy tests are essentially a form of static analysis - they check the source code, but not how it runs.

Os testes Krazy são essencialmente uma forma de análise estática - verifica o código-fonte, mas não como ele é executado.

Krazy exists as a framework comprising a number of different test runners, and a set of plugins. The test runners are called krazy2, krazy2all, and krazy2ebn. The test runners just call one or more plugins on the appropriate code, and format the results for display.

At this stage, most of the test runners are written in perl, however one is written in C++ (using Qt) and it is quite possible to add your own tests, or to modify a test - all sources are provided.

Krazy existe como um framework formado por diferentes testes, e um conjunto de plugins. Os testes são chamados de krazy2, krazy2all e krazy2ebn. Os testes apenas chamam um ou mais plugins no código apropriado, e formatam os resultados para mostrar.

Nesta fase, a maioria dos testes são escritos em perl, porém um escrito em C + + (usando Qt) e é bem possível adicionar seus próprios testes, ou para modificar um teste - todas o código fonte é fornecido.

Intsalando o Krazy

Krazy needs to be installed before use. Krazy has two different ways to be installed - you can either modify the krazy2/install.sh script and run it, or follow the instructions in the krazy2/install.txt file. I recommend the second.

Krazy precisa ser instalado antes de usar. Krazy tem duas formas diferentes de ser instalado - você pode modificar o script krazy2/install.sh e executá-lo, ou siga as instruções no arquivo krazy2/install.txt. Eu recomendo a segunda opção.

Você pode precisar instalar módulos adicionais do perl como XML::LibXML, veja como:

linux-pudb:~/krazy2 # ./install.sh 
MakeMaker FATAL: prerequisites not found.
    Tie::IxHash not installed
    XML::LibXML not installed

 Por favor instalar esses primeiros módulos e execute novamente 'perl Makefile.PL'.
linux-pudb:~/krazy2 # perl -mCPAN -e CPAN::shell

You may have to answer 25 useless questions here. In this case, just press ENTER 25 times. Then you go on like this:

cpan[1]> install XML::LibXML

O Tie::IxHash eu instalei a partir do repositório distro (libtie-ixhash-perl) e também o pacote perl-doc é necessário para instalar.

Note
Eu tive um pequeno problema com o plugin que é construída a partir do C + +, porque instalei o plugin no diretório errado. Se estiver faltando o passbyvalue plugin, então talvez seja necessário para movê-lo para o diretório que contém o resto de seus plugins.


Using Krazy

Krazy vem com uma página principal muito boa, que lhe dá várias opções e um exemplo de uso. O arquivo é gerado na instalação. Esta é definitivamente uma leitura recomendada!

Como mencionado acima, existem três testes - krazy2, krazy2ebn and krazy2all. Se você está tentando verificar um único arquivo, então krazy2 é a ferramenta certa. Se você está tentando verificar uma árvore (por exemplo, uma aplicação ou todo um módulo versionado), então krazy2all é mais útil. krazy2all não tem uma página, mas você pode obter uma lista das opções com krazy2all --help. Você também pode usar krazy2 para obter informações sobre os vários plugins que podem ajudar você a entender mais sobre krazy2all.

krazy2ebn é a ferramenta que roda sobre o código base do KDE, a EBN e não deve ser executado localmente. No entanto, por favor consulte [[# Controlando Krazy na EBN | Controle Krazy sobre] EBN] abaixo para saber como você pode controlar quais plugins são executados, e que os arquivos são processados pelo programa krazy2ebn na máquina EBN.

Lembre-se que Krazy não altera o seu código - apenas examina. Assim, você pode experimentar de modo seguro executando verificações do Krazy até ter certeza de que você entenda o que está acontecendo.

Da mesma forma, o que significa que Krazy não resolve os problemas - só tenta reportá-los. Entendendo o que está sendo reportado, e como corrigir, é com você. Você também deve lembrar que a política de commit do KDE é de não dar commit em código que você não entende. Assim, corrigir de um erro de ortografia em um comentário é bastante seguro, mas alterar cegamente o código para parar os avisos do Krazy não é uma boa idéia.


In-Code directives

Os plugins do Krazy suportam a seguinte lista de diretivas in-code:

  • //krazy:skip - nenhum teste será executado nesse arquivo.
  • //krazy:excludeall=<name1[,name2,...,nameN]> - os testes do Krazy name1, etc não serão executados nesses arquivos. Múltiplas ocorrência de krazy:excludeall são permitidas.
  • //krazy:exclude=<name1[,name2,...,nameN]> - os testes name1, etc. não serão executados na linha onde essa diretiva for encontrada (veja a next section abaixo para mais informações).

Note que essas diretivas devem ser no estilo dos comentários em C++ que podem ser colocados em qualquer lugar no arquivo (exceto embutido em comentários em C)

Omitindo false-positives

Os testes Krazy são projetados para minimizar os false-positives (isto é, os alertas que não representam problemas reais). No entanto, porque a maioria dos testes são realizados em uma única linha, existem alguns testes que podem produzir um false-positive. Por exemplo, o código que faz algo como:

QString mystring; mystring += "/";

Será sinalizado pelo verificador doublequote_chars, porque é mais eficiente para adicionar um caracter simples, como mostrado abaixo:

QString mystring; // note that we are using single quotes // this is a char, not a char array mystring += '/';

Esse mesmo verificador irá produzir um falso positivo para o código seguinte: std::string mystring; mystring += "/";

Você pode suprimir esses falsos positivos, usando um formato de comentário especial. Para excluir um plugin específico de ser executado em uma linha de código, basta adicionar um comentário em C++ que contenha a string "krazy:exclude=<plugin_name>". Os plugins disponíveis atualmente podem ser encontrados no repository.

Especificamente, para este plugin use "krazy:exclude=doublequote_chars". Por exemplo:

  lenstr = "0" + lenstr;

becomes

  lenstr = "0" + lenstr;  // krazy:exclude=doublequote_chars

Note
Usando o estilo C (/* */) comentários não vão funcionar. Você deve usar o estilo C++ (//) de comentários quando notar testes sendo ignorados.


Controlando Krazy no EBN

This section describes how to use .krazy files to control the Krazy runs on the EBN. The .krazy files are used to tell Krazy to skip over specific sub-directories, or files; or to disable certain plugins within those modules and sub-directories.

To ignore a sub-directory within a module, say kdepim/kmail, use the IGNORESUBS directory within the kdepim/.krazy file, like so:

IGNORESUBS kmail

Or you can ignore a set of directories by specifying a comma-separated list:

IGNORESUBS kmail,kontact,knode

To ignore files or directories within a module/subdir, specify a regular expression that matches the files to skip together with the SKIP directive. For example, to skip the directories kdepimlibs/kcal/libical, kdepimlibs/kcal/versit, and the kdepimlibs/kcal/fred.c file, use this directive within the kdepim/kcal/.krazy file:

SKIP /libical/\|/versit/\|fred\.c

Use the EXCLUDE directive to disable a list of plugins for all files within a module/subdir:

EXCLUDE doublequote_chars,qclasses

To override the EXCLUDE directive set from a .krazy file up in the directory hierarchy, use the CHECK command. For example, the component level .krazy file may EXCLUDE the copyright and license plugins, but those plugins can be re-enabled in a module/subdir with the CHECK directive like so:

CHECK copyright,license

Note
Individual modules can be ignored as well, but this is an EBN administrator duty controlled by component-level .krazy files within the /usr/local/src hierarchy. See the English Breakfast Network wiki for details.


Krazy Modules

Risk Ratings:

Low: Can be fixed by anyone with minimal risk of error.

Medium: Can be fixed by anyone with appropriate knowledge of C++ features involved, some testing advised.

High: Should only be fixed by maintainer/owner of code

If you don't understand the code, or you don't understand the fix, then do not fix the code.

Fixing apidox and spelling mistakes only requires a compile before submitting. All other fixes should be tested to an appropriate degree, the standard unit tests are useful for this.

Module=spelling

Risk from Fixing: Low

Spelling errors in comments and strings should be fixed as they may show up later in API documentation, handbooks, etc. Misspelled strings make the translator's job harder. Please use US English.

To exclude all checks in file comment at top of file: // krazy:excludeall=spelling

To exclude an individual check comment at the end of the line: // krazy:exclude=spelling

Module=doublequote_chars

Risk from Fixing: Low

Adding single characters to a QString is faster if the characters are QChars and not QStrings, i.e. use single quotes instead of double quotes around single characters.

The same holds for arguments to QString::startsWith(), QString::endsWith(), QString::remove(), QString::section(), and QString::split().

Use QString::remove() instead of QString::replace(foo,"")

Replace QString path = oldpath + "/" + base; with QString path = oldpath + '/' + base;

To exclude all checks in file comment at top of file: // krazy:excludeall=doublequote_chars

To exclude an individual check comment at the end of the line: // krazy:exclude=doublequote_chars

Module=nullstrassign

Risk from Fixing: Low

Do not assign QString::null or QString() to a QString. Instead use the .clear() method.

Replace fileName = QString::null; or fileName = QString(); with fileName.clear();

When returning an empty string from a method use "return QString()" When passing an empty string use "QString()".

To exclude all checks in file comment at top of file: // krazy:excludeall=nullstrassign

To exclude an individual check comment at the end of the line: // krazy:exclude=nullstrassign

Module=foreach

Message: non-const ref iterator

Risk from Fixing: Low to Medium

When not using POD types (int, double, pointer, ...) you should use const & for your foreach variables. There are two reasons for this: 1) Prevents you from the mistake of writing foreach loops that modify the list, that is 'foreach(Foo f, list) f.a = f.b = f.c = 0;' compiles but does not modify the contents of list 2) Saves a copy constructor call for each of the list elements

Be careful if dealing with pointers? False positive for bool, qlonglong and qulonglong?

http://tsdgeos.blogspot.com/2008/04/qforeach-is-your-friend.html

Replace foreach(QString str, stringList) { with foreach(const QString &str, stringList) {

Message: values or keys iteration

Risk from Fixing: Medium to High

http://tsdgeos.blogspot.com/2009/04/how-to-make-foreach-loops-that-dont.html

To exclude all checks in file comment at top of file: // krazy:excludeall=foreach

To exclude an individual check comment at the end of the line: // krazy:exclude=foreach

Module=strings

Message: QLatin1String issues

Risk from Fixing: Low to Medium

Some QString methods (like startsWith() and endsWith()) are more efficient if they are passed a QLatin1String, avoiding an implicit conversion from const char *.

Replace aString.startsWith("init") with aString.startsWith(QLatin1String("init"))

A common false positive is with QByteArray which cannot take a QLatin1String.

To exclude all checks in file comment at top of file: // krazy:excludeall=strings

To exclude an individual check comment at the end of the line: // krazy:exclude=strings

Module=includes

See http://techbase.kde.org/Policies/Library_Code_Policy#Getting_.23includes_right.

Message: duplicate includes

Risk from Fixing: Low

The same file has been included twice, remove the second occurrence.

Message: include own header first

Message: include own _p header first

Risk from Fixing: Medium

The cpp file should include their own .h and _p.h headers first in the file (but below config.h). Move the includes to the correct position. You may need to adjust includes and forward declarations in other files as a result, the compiler will advise of these.

Message: missing or improper include guard in header

Risk from Fixing: Low

Either the include guards are missing, or they are not appropriately encoded macro names, e.g. do not include the class name.

Message:

Use <..> to include installed headers.

Message:

To include Qt headers from installed headers.

To exclude all checks in file comment at top of file: // krazy:excludeall=includes

To exclude an individual check comment at the end of the line: // krazy:exclude=includes

Module=qclasses

Risk from Fixing: Medium

Deprecated Qt classes and classes that have a KDE version shouldn't be used. Also KDE versions of some Qt GUI elements provide a consistent look and feel for the KDE desktop. See http://techbase.kde.org/Policies/API_to_Avoid

Some of the K classes don't just add features to the Qt ones and might not even be based on the Qt class. Please refer to the API documentation before porting to the K classes.

To exclude all checks in file comment at top of file: // krazy:excludeall=qclasses

To exclude an individual check comment at the end of the line: // krazy:exclude=qclasses

Compiler Warnings

In addition to the various Krazy tools, you can also get valuable assistance from the warnings that the compiler emits, especially if you enable additional warnings (per the documentation for your compiler), and also if you test with more than one compiler (e.g. if you can test on Linux with both GCC and the Intel compiler; or on Linux with GCC and also on Windows with the Microsoft compiler).