Prolint is a tool for automated source code review of Progress 4GL code. It reads one or more sourcefiles and examines it for bad programming practice
When you are interested Prolint, you are encouraged to subscribe to this group where you find the on-line tools to collaborate and discuss Prolint. There is a discussion forum, you can submit issues (for bugs and enhancement requests), you can modify the on-line documentation. So subscribe, and then don't forget to go to your subscription details to enable the e-mail notification!
Rule "sharelock" gives this warning when it finds a "FIND", "FOR" or "OPEN QUERY" statement where no explicit NO-LOCK or EXCLUSIVE-LOCK is specified.
the risc:
Progress will use the default lock, which is SHARE-LOCK (unless the program is compiled using the -NL session parameter).
SHARE-LOCK is more expensive than NO-LOCK in terms of server resources. Anyway it's always better to explicitly specify the lock type and not rely on default behavior for this matter.
how to solve this:
Prolint is configured to use rules that require proparse.dll, but proparse.dll is not found.
Possible causes:
Not every rule requires proparse. For example, a rule that searches
Rule "ttnoindex" gives this warning when it finds a DEFINE TEMPTABLE statement that is defined LIKE another table but doesn't contain the USE-INDEX statement and hasn't defined an index.
The risc:
If the LIKE table has a large list of indexes then the temptable will inherit all those indexes, thereby increasing the overhead.
Known issue:
The TempTable definition may be like another temptable or table definition that has only the indexes that are needed.
How to solve this:
Make a habit of specifying the exact indexes that the program will be using regardless of whether they are the same as the LIKE table.
How to suppress these warnings:
Rule "nobrackets" gives this warning when it finds a handle:method statement without brackets. The following methods are watched for by this rule:
hQuery:OPEN-QUERY. hQuery:GET-FIRST. hQuery:GET-NEXT. hQuery:GET-PREV. hQuery:GET-LAST. hQuery:CLOSE-QUERY.
Each of these methods should really end with brackets, just like any other method. Other methods (not included in this list) will be reported by rule "noeffect" because methods without brackets look like properties.
how to solve this:
Rule "message" gives this warning when it finds a MESSAGE statement, except if the MESSAGE statement is found in ADM or ADM2 includefiles or
if the MESSAGE statement was generated by the Application Builder (like the message that says that the specified .wrx could not be found).
the risc:
Many frameworks are using alternative error handling functions not including the MESSAGE ... VIEW-AS ALERT-BOX statement, like dialogs with context-sensitive help or built-in logging functionality.
In organizations where such frameworks are used, it is usually forbidden to use the MESSAGE statement and use the alternative instead; this rule helps to enforce this.
Rule "strattrib" gives this warning when it finds a string literal that has no string attributes or wrong string attributes.
String attributes are used primarily by the Translation Manager. Examples of strings with attributes are: "welcome":T, "prolint/rules":U.
NO string attributes is just that: no string attributes.
WRONG string attributes are all string attributes except :U and :T (you will probably want to modify this, take a look at the source in prolint/rules/strattrib.p)
the risc:
The program is not ready for Translation Manager.
how to solve this:
Rule "query" gives this warning when it finds a GET PREV or GET LAST statement for a query that was defined without the SCROLLING option. This is to warn for compatibility with Oracle dataservers: Oracle requires the SCROLLING option when you want to GET PREV or GET LAST.
Rule "nocomment" gives this warning when it finds an internal procedure or user-defined function which does not begin with a comment.
PROCEDURE WhatAreWeDoingHere : DEFINE INPUT PARAMETER dx AS DECIMAL NO-UNDO. DEFINE INPUT PARAMETER dy AS DECIMAL NO-UNDO. DEFINE OUTPUT PARAMETER dz AS DECIMAL NO-UNDO. - a bunch of arcane code here - END PROCEDURE. |
An unmodified default UIB-generated comment is NOT accepted as a valid comment.
the risc:
Rule "findstate-tt" gives this warning when it finds a "FIND" statement without [ FIRST | LAST | NEXT | PREV | CURRENT ] and has no 'IF AMBIGUOUS' statement immediately following.
The risc:
If the FIND statement returns more than one record an error will occur when an attempt to access the record is made. Also, if not already searching on an Unique index, without the qualifier the PROGRESS engine will look to see if there is another record that matches the criteria increasing the search time. However, even in the case of searching on an Unique index, it is better coding practice to add the qualifier as it indicates to other developers what your intent is.
Rule "unquoted" gives this warning when it finds a string literal without quotes.
Strings "w1" and "w2" are not quoted:
DEFINE VARIABLE RADIO-SET-2 AS INTEGER VIEW-AS RADIO-SET VERTICAL RADIO-BUTTONS w1, 0, w2, 1, "w3", 2 SIZE 19 BY 2 NO-UNDO. |
Progress will create a file named "logfile" in the current directory:
DEFINE VARIABLE logfile AS CHARACTER INITIAL "c:\temp\errorlog.txt". OUTPUT TO logfile. |
the risc:
Rule "substitute" gives this warning when it finds a
concatenation of several strings. For example :
MESSAGE "customer " + fill-in-1:screen-value + " already
exists".
the risc:
A translator will only get to see the separate
strings, e.g. "customer " and " already exists" and will
have a hard time understanding in which context these
two fragments are used.
how to solve this:
use the SUBSTITUTE() function:
MESSAGE SUBSTITUTE("customer &1 already exists", fill-
in-1:screen-value).
How to suppress these warnings:
Rule "tablename" gives this warning when it finds a filedname that is not qualified with a tablename.
FOR EACH customer : DISPLAY cust-num. /* should be customer.cust-num */ END. /* typo in variable: should be "name" instead "nane" */ DEFINE VARIABLE nane AS CHARACTER NO-UNDO. ASSIGN name = "Bill". /* expect to assign variable, but assigns customer.name instead! */ |
the risc:
Humans cannot see if "cust-num" is a variable or a database fieldname. Hard to find run-time bugs can result from small typos as illustrated in the example.
Rule "maxchar" gives this warning when it finds a string constant that is longer that 188 characters,
unless the string has the :U attribute (untranslatable).
the risc:
"Translation Manager" can not import those long strings. It has an index on string value, and indexes in Progress are
limited to 188 chars max.
how to solve this:
Cut the string constant in smaller pieces.
implementation:
This rule is implemented in Turbolint
Rule "shared" gives this warning when it finds a "DEFINE" statement that contains a SHARE phrase (like SHARED, NEW SHARED, NEW GLOBAL SHARED).
Shared objects are generally considered as "not done", especially in a non-modal application since procedures may be run in random order and in multiple instances.
In general it is much better to avoid SHARED objects and replace them by parameters, or have those objects stored in persistent procedures and maintained by its internal procedures.
exceptions:
Rule "oflink" gives this warning when it finds a statement that uses OF instead WHERE, as in "EACH order OF customer".
the risc:
If an "OF"-join is used, you risk that Progress may select the wrong index. Especially when you modify or add indexes and recompile the source in the future.
how to solve this:
Rewrite the statement so that it contains a WHERE-clause.
How to suppress these warnings:
You can put directive {&_proparse_ prolint-nowarn(oflink)} directly before the statement.