This chapter will explain the various configuration options for Prolint
# this file specifies which particular warnings should be excluded. The rules will # still be executed, but warnings are intercepted if they match this file. # You can also consider using {&_proparse_ prolint-nowarn(ruleid,ruleid)} directives # # format: # sourcefile|rules # # sourcefile : spell exactly as it appears in "Prolint result window", # wildcards are accepted. CAN-DO rules apply # rule : comma separated list of identifiers of the rules that gives the warning, # wildcards are accepted. CAN-DO rules apply # # empty lines or lines matching #* are ignored # exclude everything from directories adm and adm2: adm/*.i|* adm2/*.i|* # from file ifindent.i, allow rules ifindent1 and ifindent2 but exclude all other rules: prolint/regrtest/ifindent.i|!ifindent*,*
# this file specifies which particular warnings should be suppressed. The rules will # still be executed, but warnings are intercepted if they match this file. # You can also consider using {&_proparse_ prolint-nowarn(ruleid,ruleid)} directives # # format: # sourcefile|rule|linenumbers # sourcefile|_file-size|size # # sourcefile : spell exactly as it appears in "Prolint result window" # rule : identifier of the rule that gives the warning # linenumbers: comma separated list of linenumbers where the warning would occur when not suppressed # # size : the filesize of the sourcefile, in bytes # if _file-size is not specified, or if size doesn't match the actual size of the sourcefile, # all lines for sourcefile will be invalid. So after you edit a sourcefile no warnings will be suppressed. # # empty lines or lines matching #* are ignored # unfortunately when you lint prolint itself you will get a lot of warnings from proparse.i proparse/api/proparse.i|_file-size|3179 proparse/api/proparse.i|varusage|8,10,12,14,16,18,28,30,34,36,38,40,42,44,48,50,62,64,67,70,72,74,76,78,80,84 proparse/api/proparse.i|nocomment|8 proparse/api/proparse.i|nocomment|10 proparse/api/proparse.i|nocomment|12 proparse/api/proparse.i|nocomment|14 proparse/api/proparse.i|nocomment|16 proparse/api/proparse.i|nocomment|18 proparse/api/proparse.i|nocomment|20 proparse/api/proparse.i|nocomment|22 proparse/api/proparse.i|nocomment|24 proparse/api/proparse.i|nocomment|26 proparse/api/proparse.i|nocomment|28 proparse/api/proparse.i|nocomment|30 proparse/api/proparse.i|nocomment|32 proparse/api/proparse.i|nocomment|34 proparse/api/proparse.i|nocomment|36 proparse/api/proparse.i|nocomment|38 proparse/api/proparse.i|nocomment|40 proparse/api/proparse.i|nocomment|42 proparse/api/proparse.i|nocomment|44 proparse/api/proparse.i|nocomment|46 proparse/api/proparse.i|nocomment|48 proparse/api/proparse.i|nocomment|50 proparse/api/proparse.i|nocomment|52 proparse/api/proparse.i|nocomment|54 proparse/api/proparse.i|nocomment|56 proparse/api/proparse.i|nocomment|58 proparse/api/proparse.i|nocomment|60 proparse/api/proparse.i|nocomment|62 proparse/api/proparse.i|nocomment|64 proparse/api/proparse.i|nocomment|66 proparse/api/proparse.i|nocomment|68 proparse/api/proparse.i|nocomment|69 proparse/api/proparse.i|nocomment|70 proparse/api/proparse.i|nocomment|72 proparse/api/proparse.i|nocomment|74 proparse/api/proparse.i|nocomment|76 proparse/api/proparse.i|nocomment|78 proparse/api/proparse.i|nocomment|80 proparse/api/proparse.i|nocomment|82 proparse/api/proparse.i|nocomment|84
Prolintdb consists of an outputhandler to write warnings to a database, and a couple of programs to help you query the database.
the user story:
Suppose you have a pretty large software project and want to inspect it with Prolint. It will take a long while for Prolint to finish the job,
so you would like to run Prolint unattended and look at the warnings later. Since it is a large software project Prolint will probably find
thousands of warnings, so you need tools to help you generate an overview.
Make sure the prolintdb database is connected with logical database name "prolintdb".
Run Prolint as usual, but select a profile that uses outputhandler "prolintdb.p". This outputhandler is responsible for writing warnings to the database.
When you do not want to write anything to the database, then just don't use outputhandler "prolintdb.p".
To query warnings that are stored in the prolint database, you can use the windows "Statistics by rule" and "Statistics by subdirectory".
These windows can be launched from the Prolint Desktop window.
These windows don't actually query the warnings that are generated by the outputhandler, but they query statistics.
These statistics are also stored in the database but need to be calculated manually: just press
button "Recalculate" in one of the statistics windows. Statistics are not automatically refreshed after you run Prolint, you just need to press the Recalculate-button.
From the two statistics windows, you can use button "Show Results" to see the actual Prolint warnings that were saved by the outputhandler.
This button launches the usual "Prolint Results Window" and publishes the selected warnings to that window.
Once the selected warnings are visible in the Results window, you can use all the features of that window including: open the sourcefiles at the specified line number, re-lint the selected compilation unit, etc.
Please notice that the "Prolint Results window" assumes that you have been using a profile named "prolintdb".
When you want to re-lint a selected compilation unit, the Results window will try to do that with profile "prolintdb".
So it is required to actually have such a profile, and to make sure that this profile uses outputhandler "prolintdb.p".
You don't always want to run every rule. A "profile" contains a specification of the rules you want to skip and which outputhandlers you want to use. You can create as many profiles as you want.
For example, you may want to create a profile named "indexes" that only uses rules "nowhere", "sortaccess" and "wholeindex" and writes its output to HTML and to a tab-delimited file. Or you may want to ue profile "Ed4Win" that writes its output to the build-window in ED for Windows.
Each subdirectory in "prolint/settings" is a profile. Each of those subdirectories contains a couple of ascii-files to define the characteristics of the profile.
Profiles in "prolint/settings" are considered to be "shared" profiles.
In addition to "prolint/settings" you can also create a directory "local-prolint/settings" anywhere in your propath. Each subdirectory in "local-prolint/settings" is also a profile, and these are considered to be "local" profiles.
you can achieve two different goals with local profiles:
The list of profiles, available in a prolint-session, is merged from profiles in both "prolint/settings" and "local-prolint/settings".
A local profile overrides the shared profile, unless the shared profile contains a file named "no-local-settings.lk". The contents of this file is not important, but the existence of such a file notifies prolint that only the shared profile should be used and the local profile will be ignored.
for a GUI-window to modify the settings described here:
run prolint/core/lintcfg.w("")
See page "lintcfg" for features of this window.
specifies which rules to run and allows to customize severities.
inherits prolint/rules/rules.d
each line has two or three fields:
specifies a list of outputhandlers to start for this profile.
these are programnames found in directory prolint/outputhandlers.
Prolint 'knows' for each outputhandler if it requires a specific Progress version or GUI/ChUI mode. It will not run the
outputhandlers that don't match the current Progress session. This means you can safely select "logwin" even if you
are running a ChUI session, because in that case Prolint will simply skip "logwin".
If file handlers.d is missing, or if the file is empty, or if it only contains outputhandlers that are not supported
in the current Progress session, then Prolint will terminate with an error message.
Same purpose as putting {&_proparse_ prolint-nowarn(ruleid)} in source, but may be more convenient if the source is
maintained by someone else (like sources in adm2/src)
See example nowarn.lst for details.
for a GUI-window to modify the settings described here:
run prolint/core/lintcfg.w("")
Directory prolint/settings shows an example of how custom profiles can be used.
Each profile represents a subdirectory in prolint/settings.
Such a subdirectory may contain configuration files describing the behavior of Prolint.
The name of the custom profile is passed to Prolint as an input parameter. For example:
RUN prolint/core/prolint.p (sourcefile, ttemptablehandle, "relaxed", true).
tells prolint to look for configuration files in directory prolint/settings/relaxed.
The configuration files in this directory may tell prolint to skip all rules with severity<6, for example.
If the parameter is blank or points to a non-existing directory, prolint will
use directory prolint/settings instead because this contains the default settings.
Profiles can be attractive when prolint is called from other ADE-tools to specify the
context where prolint is called from.
For example, Roundtable might run prolint.p(.., .., "rtb check-in",..)
during its pre-validation on check-in.
The Application compiler might run prolint.p(.., .., "application compiler",..)
which might tell prolint to write results to a logfile instead of using the results window.
Note: directories are searched in PROPATH.
file exteditor.cfg specifies how a source file can be opened in an external editor, like for example Ed4Win or UltraEdit etc.
exteditor.cfg contains just two lines:
These two lines are passed to the operating system. Each of these lines may contain &1 and &2, which are substituted by
filename and linenumber respectively, using the Progress SUBSTITUTE function.
example (for UltraEdit-32) :
"C:\Program Files\UltraEdit\UEDIT32.EXE" "&1/&2"
(in this example the double quotes are used for supporting long filenames.)
If your program requires database aliases to exist before it will compile, then you must use this file to tell Prolint about your database aliases before that program can be parsed.
The file may contain several lines, each line contains two fields: aliasname and databasename. Example:
"demo" "sports2000" "archive" "sports2001"
In this example, "demo" is an alias for database "sports2000" and "archive" is an alias for database "sports2001".
See profiles
Sometimes Prolint may raise a warning you don't agree with.
For example, rule "noundo" might warn that a specific temp-table is defined without NO-UNDO while you are certain that not using no-undo
is intentional.
In such cases you may want to suppress the Prolint warning.
There are two separate ways to suppress warnings:
Finally, if you really completely disagree with a rule, you can put it in the "skiprules" list. In that case Prolint will pretend the rule does not exist at all. The "skiprules" list is file "prolint/custom/rules/skiprules.lst". Its format is simple: each line contains one rule-id.
Let's begin with an example:
{&_proparse_ prolint-nowarn(noundo)} DEFINE TEMP-TABLE tt_mytable FIELD code AS CHAR FIELD desc AS CHAR INIT "<description>" INDEX idx_code AS PRIMARY UNIQUE code. |
When Prolint executes rule "noundo" it will simply skip the statement, the statement is invisible to the rule.
Prolint will still give a warning for rule "abbrevkwd" because INIT is an abbreviation for INITIAL, and a warning for
rule "strattrib" because "<description>" does not have any string attributes.
If you are sure you want to suppress these warnings too, you can extend the _proparse_ directive to:
{&_proparse_ prolint-nowarn(noundo,abbrevkwd,strattrib)} DEFINE TEMP-TABLE tt_mytable FIELD code AS CHAR FIELD desc AS CHAR INIT "<description>" INDEX idx_code AS PRIMARY UNIQUE code. |
Note:
There is no way to suppress all warnings.
There is also no way to suppress warnings for a larger scope than just one single statement.
This is intentional: adding _proparse_ directives is meant to be more work than fixing the cause of the warning.
Another note:
Please don't use the _proparse_ directive immediately after the ELSE keyword.
/* this does not work and confuses the parser: */ IF False THEN RUN first.p. ELSE {&_proparse_ prolint-nowarn(runname)} RUN Second.p. /* this is better: */ IF False THEN RUN first.p. ELSE DO: {&_proparse_ prolint-nowarn(runname)} RUN Second.p. END. /* or this is also fine: */ {&_proparse_ prolint-nowarn(runname)} IF False THEN RUN first.p. ELSE RUN Second.p. |
Filters intercept warnings after they are created by a rule, but before they are published to outputhandlers. Filters can modify or hide warnings.
You can create new filters, or configure existing filters. See topic "filter plug-ins" for more information.
Note: This is history. Turbolint is removed from Prolint release 74, because Turbolint was not compatible with Proparse.NET
Turbolint is a Dynamic Link Library that contains 3GL versions for some of the rules. The purpose of Turbolint is to improve the overall performance of Prolint, by running the 3GL rules instead of the 4GL rules.
The rules contained in Turbolint are supposed to be identical to the 4GL rules, only faster.
Turbolint.dll does not contain 3GL versions of every existing 4GL rule.
By default, if a 3GL rule exists in Turbolint.dll, then Prolint will use this 3GL version instead of the 4GL version.
Obviously if a rule does not exists in Turbolint.dll then Prolint will use the 4GL version.
Turbolint.dll currently contains the following rules:
abbrevkwd,blocklabel,ifindent,ifindent1,ifindent2,noundo,nowhere,recid,runargs,sepdbui,substitute,varusage
The ultimate goal is not to have every rule in Turbolint, only the really slow ones.
Sometimes you may want to prefer the 4GL version of a rule, even if Turbolint contains a 3GL version. For example when you are modifying or debugging the rule.
There are different ways to force Prolint to use the 4GL rule:
custom rules always take precendence over standard rules. Just copy the rule from directory "prolint/rules" to "prolint/custom/rules". Because if Prolint can find a rule in "prolint/custom/rules" then it's a custom rule, and will be run instead rules with the same name in "prolint/rules" or turbolint.
If you don't want to make a custom rule, but still want to run a 4GL rule instead of a 3GL rule, then you can specify so in file
"prolint/custom/prolint.properties.p" :
For example:
RUN SetProlintProperty ("Turbolint.RulesToIgnore", "noundo,varusage").
will force Turbolint to NOT run its built-in versions of rule "noundo"
and "varusage", and Prolint will run the 4GL versions instead. See
file prolint/prolint.properties.p for more details.
Finally, you can simply remove or rename file "prolint/turbolint.dll" so Prolint cannot find it. Prolint will then simply fall back to its 4GL rules.