From michael at freepascal.org Wed Jul 8 22:14:06 2026 From: michael at freepascal.org (Michael Van Canneyt) Date: Wed, 8 Jul 2026 22:14:06 +0200 (CEST) Subject: [fpc-pascal] FpSonar - a pascal linter Message-ID: Hi, I've finished something I have been brooding on for some months now: FPSonar - a Object Pascal linter, written in Object Pascal What does it do? It has roughly 140-150 rules on how pascal code should be written to be readable. It parses your code (using fcl-passrc) and will check all these rules. It will then generate a report. Examples of checks: RoutineTooLarge - too long routines are flagged. TooManyParameters - Procedure takes too many parameters. TooManyNestedRoutines - too many local nested routines. RemoveUnusedConstant - there is a constant that is never used. FileNotTooManyClasses - too many classes in a file. FormatArgumentType - wrong type for Format() argument. LowercaseKeywords - keywords should be lowercase. Some of these the compiler will flag (or the IDE code observer), but most are not. There are many of them. You can configure these checks (how long is too long, what is too many parameters etc.) or disable checks altogether. The configuration file is a JSON file. You can also mark a line in code so it will not be checked: SomeCommand; // NOSONAR The NOSONAR comment will suppress any warnings about that line. The basic rule is: if the linter cannot determine with certainty that something is wrong, it will not report it. For example, if it cannot with certainty determine the type of a format argument, then no error/warning will be reported about a type mismatch. In order to do its job properly, it sometimes needs to know what the FPC units contain, and it automatically runs FPC's ppudump tool to find out - so it does not need to parse the FPC code (although it can also do the latter). In case you don't want that, you can let it simply use some built-in basic copies of some essential FPC units (system, sysutils, classes). To start using this tool on an old codebase can prove daunting - you can start out with many 1000's of 'errors'. In order to help with that you can make a baseline, a snapshot which you can compare against in subsequent runs so you at least don't make things worse. This gives you time to slowly fix the existing issues while ensuring you don't add new ones. I'm still working on a Lazarus IDE plugin. In case you were wondering about the name: it's a reference to SonarQube, a Java tool which does something similar (even for Pascal), but is 1000 times harder to use than fpSonar. If you find you're missing checks or have ideas for additional checks, feel free to contact me. if they can be implemented, I will look at it. Enjoy, Michael. From timcoates.solutions at gmail.com Thu Jul 9 00:52:20 2026 From: timcoates.solutions at gmail.com (Tim Coates) Date: Thu, 9 Jul 2026 08:52:20 +1000 Subject: [fpc-pascal] FpSonar - a pascal linter In-Reply-To: References: Message-ID: Hi Michael, Link please? I'd love to try it out. Tim On Thu, 9 July 2026, 6:22?am Michael Van Canneyt via fpc-pascal, < fpc-pascal at lists.freepascal.org> wrote: > > Hi, > > I've finished something I have been brooding on for some months now: > > FPSonar - a Object Pascal linter, written in Object Pascal > > What does it do? > > It has roughly 140-150 rules on how pascal code should be written to be > readable. It parses your code (using fcl-passrc) and will check all these > rules. It will then generate a report. > > Examples of checks: > > RoutineTooLarge - too long routines are flagged. > > TooManyParameters - Procedure takes too many parameters. > > TooManyNestedRoutines - too many local nested routines. > > RemoveUnusedConstant - there is a constant that is never used. > > FileNotTooManyClasses - too many classes in a file. > > FormatArgumentType - wrong type for Format() argument. > > LowercaseKeywords - keywords should be lowercase. > > Some of these the compiler will flag (or the IDE code observer), > but most are not. There are many of them. > > You can configure these checks (how long is too long, what is too many > parameters etc.) or disable checks altogether. The configuration file is a > JSON file. > > You can also mark a line in code so it will not be checked: > SomeCommand; // NOSONAR > The NOSONAR comment will suppress any warnings about that line. > > The basic rule is: if the linter cannot determine with certainty that > something is wrong, it will not report it. For example, if it cannot with > certainty determine the type of a format argument, then no error/warning > will be reported about a type mismatch. > > In order to do its job properly, it sometimes needs to know what the FPC > units > contain, and it automatically runs FPC's ppudump tool to find out - so it > does not need to parse the FPC code (although it can also do the latter). > In case you don't want that, you can let it simply use some built-in basic > copies of some essential FPC units (system, sysutils, classes). > > To start using this tool on an old codebase can prove daunting - you can > start out with many 1000's of 'errors'. In order to help with that you can > make a baseline, a snapshot which you can compare against in subsequent > runs > so you at least don't make things worse. This gives you time to slowly fix > the existing issues while ensuring you don't add new ones. > > I'm still working on a Lazarus IDE plugin. > > In case you were wondering about the name: it's a reference to SonarQube, > a Java tool which does something similar (even for Pascal), > but is 1000 times harder to use than fpSonar. > > If you find you're missing checks or have ideas for additional checks, > feel free to contact me. if they can be implemented, I will look at it. > > Enjoy, > > Michael. > _______________________________________________ > fpc-pascal maillist - fpc-pascal at lists.freepascal.org > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal > -------------- next part -------------- An HTML attachment was scrubbed... URL: From michael at freepascal.org Thu Jul 9 08:41:24 2026 From: michael at freepascal.org (Michael Van Canneyt) Date: Thu, 9 Jul 2026 08:41:24 +0200 (CEST) Subject: [fpc-pascal] FpSonar - a pascal linter In-Reply-To: References: Message-ID: <418d90af-1005-528f-fff0-07edf9417678@freepascal.org> Sorry, I should have been more clear. This is part of fpc. So it's in gitlab: https://gitlab.com/freepascal.org/fpc/source/-/tree/main/utils/fpsonar The code compiles with FPC 3.2.2, though, I made sure of that. I'll see about making a zip with just the fcl-passrc/sonar units, and report back. Michael. On Thu, 9 Jul 2026, Tim Coates via fpc-pascal wrote: > Hi Michael, > > Link please? I'd love to try it out. > > Tim > > On Thu, 9 July 2026, 6:22?am Michael Van Canneyt via fpc-pascal, < > fpc-pascal at lists.freepascal.org> wrote: > >> >> Hi, >> >> I've finished something I have been brooding on for some months now: >> >> FPSonar - a Object Pascal linter, written in Object Pascal >> >> What does it do? >> >> It has roughly 140-150 rules on how pascal code should be written to be >> readable. It parses your code (using fcl-passrc) and will check all these >> rules. It will then generate a report. >> >> Examples of checks: >> >> RoutineTooLarge - too long routines are flagged. >> >> TooManyParameters - Procedure takes too many parameters. >> >> TooManyNestedRoutines - too many local nested routines. >> >> RemoveUnusedConstant - there is a constant that is never used. >> >> FileNotTooManyClasses - too many classes in a file. >> >> FormatArgumentType - wrong type for Format() argument. >> >> LowercaseKeywords - keywords should be lowercase. >> >> Some of these the compiler will flag (or the IDE code observer), >> but most are not. There are many of them. >> >> You can configure these checks (how long is too long, what is too many >> parameters etc.) or disable checks altogether. The configuration file is a >> JSON file. >> >> You can also mark a line in code so it will not be checked: >> SomeCommand; // NOSONAR >> The NOSONAR comment will suppress any warnings about that line. >> >> The basic rule is: if the linter cannot determine with certainty that >> something is wrong, it will not report it. For example, if it cannot with >> certainty determine the type of a format argument, then no error/warning >> will be reported about a type mismatch. >> >> In order to do its job properly, it sometimes needs to know what the FPC >> units >> contain, and it automatically runs FPC's ppudump tool to find out - so it >> does not need to parse the FPC code (although it can also do the latter). >> In case you don't want that, you can let it simply use some built-in basic >> copies of some essential FPC units (system, sysutils, classes). >> >> To start using this tool on an old codebase can prove daunting - you can >> start out with many 1000's of 'errors'. In order to help with that you can >> make a baseline, a snapshot which you can compare against in subsequent >> runs >> so you at least don't make things worse. This gives you time to slowly fix >> the existing issues while ensuring you don't add new ones. >> >> I'm still working on a Lazarus IDE plugin. >> >> In case you were wondering about the name: it's a reference to SonarQube, >> a Java tool which does something similar (even for Pascal), >> but is 1000 times harder to use than fpSonar. >> >> If you find you're missing checks or have ideas for additional checks, >> feel free to contact me. if they can be implemented, I will look at it. >> >> Enjoy, >> >> Michael. >> _______________________________________________ >> fpc-pascal maillist - fpc-pascal at lists.freepascal.org >> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal >> > From michael at freepascal.org Sun Jul 12 11:08:44 2026 From: michael at freepascal.org (Michael Van Canneyt) Date: Sun, 12 Jul 2026 11:08:44 +0200 (CEST) Subject: [fpc-pascal] FpSonar - a pascal linter In-Reply-To: <418d90af-1005-528f-fff0-07edf9417678@freepascal.org> References: <418d90af-1005-528f-fff0-07edf9417678@freepascal.org> Message-ID: <6ddd4f09-34cb-74fd-043a-3bf468512d20@freepascal.org> Hi, I published the fpsonar plugin for lazarus. https://gitlab.com/freepascal.org/fpsonar It also contains the command-line utility. The plugin/cli build with FPC 3.2.2 and FPC 3.3.1. I think the core engine and plugin are feature-complete as far as checking is concerned, but ideas for improvement or new rules are always welcome. I'll look into adding quick-fixes to the IDE plugin. Michael. On Thu, 9 Jul 2026, Michael Van Canneyt wrote: > > Sorry, I should have been more clear. This is part of fpc. > > So it's in gitlab: > > https://gitlab.com/freepascal.org/fpc/source/-/tree/main/utils/fpsonar > > The code compiles with FPC 3.2.2, though, I made sure of that. I'll see about > making a zip with just the fcl-passrc/sonar units, and report back. > > Michael. > > On Thu, 9 Jul 2026, Tim Coates via fpc-pascal wrote: > >> Hi Michael, >> >> Link please? I'd love to try it out. >> >> Tim >> >> On Thu, 9 July 2026, 6:22?am Michael Van Canneyt via fpc-pascal, < >> fpc-pascal at lists.freepascal.org> wrote: >> >>> >>> Hi, >>> >>> I've finished something I have been brooding on for some months now: >>> >>> FPSonar - a Object Pascal linter, written in Object Pascal >>> >>> What does it do? >>> >>> It has roughly 140-150 rules on how pascal code should be written to be >>> readable. It parses your code (using fcl-passrc) and will check all these >>> rules. It will then generate a report. >>> >>> Examples of checks: >>> >>> RoutineTooLarge - too long routines are flagged. >>> >>> TooManyParameters - Procedure takes too many parameters. >>> >>> TooManyNestedRoutines - too many local nested routines. >>> >>> RemoveUnusedConstant - there is a constant that is never used. >>> >>> FileNotTooManyClasses - too many classes in a file. >>> >>> FormatArgumentType - wrong type for Format() argument. >>> >>> LowercaseKeywords - keywords should be lowercase. >>> >>> Some of these the compiler will flag (or the IDE code observer), >>> but most are not. There are many of them. >>> >>> You can configure these checks (how long is too long, what is too many >>> parameters etc.) or disable checks altogether. The configuration file is a >>> JSON file. >>> >>> You can also mark a line in code so it will not be checked: >>> SomeCommand; // NOSONAR >>> The NOSONAR comment will suppress any warnings about that line. >>> >>> The basic rule is: if the linter cannot determine with certainty that >>> something is wrong, it will not report it. For example, if it cannot with >>> certainty determine the type of a format argument, then no error/warning >>> will be reported about a type mismatch. >>> >>> In order to do its job properly, it sometimes needs to know what the FPC >>> units >>> contain, and it automatically runs FPC's ppudump tool to find out - so it >>> does not need to parse the FPC code (although it can also do the latter). >>> In case you don't want that, you can let it simply use some built-in basic >>> copies of some essential FPC units (system, sysutils, classes). >>> >>> To start using this tool on an old codebase can prove daunting - you can >>> start out with many 1000's of 'errors'. In order to help with that you can >>> make a baseline, a snapshot which you can compare against in subsequent >>> runs >>> so you at least don't make things worse. This gives you time to slowly fix >>> the existing issues while ensuring you don't add new ones. >>> >>> I'm still working on a Lazarus IDE plugin. >>> >>> In case you were wondering about the name: it's a reference to SonarQube, >>> a Java tool which does something similar (even for Pascal), >>> but is 1000 times harder to use than fpSonar. >>> >>> If you find you're missing checks or have ideas for additional checks, >>> feel free to contact me. if they can be implemented, I will look at it. >>> >>> Enjoy, >>> >>> Michael. >>> _______________________________________________ >>> fpc-pascal maillist - fpc-pascal at lists.freepascal.org >>> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal >>> > From adriaan at adriaan.biz Mon Jul 20 10:13:33 2026 From: adriaan at adriaan.biz (Adriaan van Os) Date: Mon, 20 Jul 2026 08:13:33 +0000 (UTC) Subject: [fpc-pascal] POpen en PClose Message-ID: <645af5d0-3b91-4176-aa5c-cc02ccd92b96@adriaan.biz> I am looking at the implementation of POpen and PClose in the runtime-library for Darwin (or more general for UNIX). It seems like it doesn't call into libc popen and pclose, but instead follows its own implementation in unix.pp in POpen_internal. I am just curious to know the reason. Regards, Adriaan van Os -------------- next part -------------- An HTML attachment was scrubbed... URL: From michael at freepascal.org Mon Jul 20 11:43:49 2026 From: michael at freepascal.org (Michael Van Canneyt) Date: Mon, 20 Jul 2026 11:43:49 +0200 (CEST) Subject: [fpc-pascal] POpen en PClose In-Reply-To: <645af5d0-3b91-4176-aa5c-cc02ccd92b96@adriaan.biz> References: <645af5d0-3b91-4176-aa5c-cc02ccd92b96@adriaan.biz> Message-ID: On Mon, 20 Jul 2026, Adriaan van Os via fpc-pascal wrote: > > I am looking at the implementation of POpen and PClose in the runtime-library > for Darwin (or more general for UNIX). It seems like it doesn't call into > libc popen and pclose, but instead follows its own implementation in unix.pp > in POpen_internal. I am just curious to know the reason. - Because on linux we're independent of libc. - IIRC the libc version uses the C FILE type, which is not compatible with the file descriptor we use elsewhere. Introducing that would require lots of wiring to handle both paths. Michael. From fpc at pascalprogramming.org Mon Jul 20 11:40:10 2026 From: fpc at pascalprogramming.org (Marco van de Voort) Date: Mon, 20 Jul 2026 11:40:10 +0200 Subject: [fpc-pascal] POpen en PClose In-Reply-To: <645af5d0-3b91-4176-aa5c-cc02ccd92b96@adriaan.biz> References: <645af5d0-3b91-4176-aa5c-cc02ccd92b96@adriaan.biz> Message-ID: <081cab29-43c5-4180-9e5c-f99420c544b2@pascalprogramming.org> Op 20-7-2026 om 10:13 schreef Adriaan van Os via fpc-pascal: > > I am looking at the implementation of POpen and PClose in the > runtime-library for Darwin (or more general for UNIX). It seems like > it doesn't call into libc popen and pclose, but instead follows its > own implementation in unix.pp in POpen_internal. I am just curious to > know the reason. > Phew, that was over twenty years ago, but afaik the reason is that libc popen and pclose us C FILE descriptors, which the RTL in general doesn't use to avoid a mix of functions with pascal and C file types. So popen/pclose are a more high level (FILE * using) part of libc, while we tend to only use the basis. From michael at freepascal.org Mon Jul 20 11:57:05 2026 From: michael at freepascal.org (Michael Van Canneyt) Date: Mon, 20 Jul 2026 11:57:05 +0200 (CEST) Subject: [fpc-pascal] POpen en PClose In-Reply-To: <081cab29-43c5-4180-9e5c-f99420c544b2@pascalprogramming.org> References: <645af5d0-3b91-4176-aa5c-cc02ccd92b96@adriaan.biz> <081cab29-43c5-4180-9e5c-f99420c544b2@pascalprogramming.org> Message-ID: <65e5636b-7e86-221d-87d6-181ea637481c@freepascal.org> On Mon, 20 Jul 2026, Marco van de Voort via fpc-pascal wrote: > > Op 20-7-2026 om 10:13 schreef Adriaan van Os via fpc-pascal: >> >> I am looking at the implementation of POpen and PClose in the >> runtime-library for Darwin (or more general for UNIX). It seems like it >> doesn't call into libc popen and pclose, but instead follows its own >> implementation in unix.pp in POpen_internal. I am just curious to know the >> reason. >> > Phew, that was over twenty years ago, but afaik the reason is that libc popen > and pclose us C FILE descriptors, which the RTL in general doesn't use to > avoid a mix of functions with pascal and C file types. > > So popen/pclose are a more high level (FILE * using) part of libc, while we > tend to only use the basis. Glad our memories agree on this :-) Michael. From fpc at pascalprogramming.org Mon Jul 20 12:02:15 2026 From: fpc at pascalprogramming.org (Marco van de Voort) Date: Mon, 20 Jul 2026 12:02:15 +0200 Subject: [fpc-pascal] POpen en PClose In-Reply-To: <65e5636b-7e86-221d-87d6-181ea637481c@freepascal.org> References: <645af5d0-3b91-4176-aa5c-cc02ccd92b96@adriaan.biz> <081cab29-43c5-4180-9e5c-f99420c544b2@pascalprogramming.org> <65e5636b-7e86-221d-87d6-181ea637481c@freepascal.org> Message-ID: <96854e10-aee6-4d6e-bcd7-d2e88cdb90fd@pascalprogramming.org> Op 20-7-2026 om 11:57 schreef Michael Van Canneyt via fpc-pascal: >>> >>> I am looking at the implementation of POpen and PClose in the >>> runtime-library for Darwin (or more general for UNIX). It seems like >>> it doesn't call into libc popen and pclose, but instead follows its >>> own implementation in unix.pp in POpen_internal. I am just curious >>> to know the reason. >>> >> Phew, that was over twenty years ago, but afaik the reason is that >> libc popen and pclose us C FILE descriptors, which the RTL in general >> doesn't use to avoid a mix of functions with pascal and C file types. >> >> So popen/pclose are a more high level (FILE * using) part of libc, >> while we tend to only use the basis. > > Glad our memories agree on this :-) Well aside from the fact that FreeBSD was the architecture where the baseunix/unix RTL? was done. The port to Linux was only done later :-) This shows the tension a bit between libc the system lib, and libc the C runtime. We are only interested in the system lib part. From michael at freepascal.org Mon Jul 20 12:07:34 2026 From: michael at freepascal.org (Michael Van Canneyt) Date: Mon, 20 Jul 2026 12:07:34 +0200 (CEST) Subject: [fpc-pascal] POpen en PClose In-Reply-To: <96854e10-aee6-4d6e-bcd7-d2e88cdb90fd@pascalprogramming.org> References: <645af5d0-3b91-4176-aa5c-cc02ccd92b96@adriaan.biz> <081cab29-43c5-4180-9e5c-f99420c544b2@pascalprogramming.org> <65e5636b-7e86-221d-87d6-181ea637481c@freepascal.org> <96854e10-aee6-4d6e-bcd7-d2e88cdb90fd@pascalprogramming.org> Message-ID: <995cc048-944a-5c4a-1aaf-e798431cb516@freepascal.org> On Mon, 20 Jul 2026, Marco van de Voort via fpc-pascal wrote: > > Op 20-7-2026 om 11:57 schreef Michael Van Canneyt via fpc-pascal: >>>> >>>> I am looking at the implementation of POpen and PClose in the >>>> runtime-library for Darwin (or more general for UNIX). It seems like >>>> it doesn't call into libc popen and pclose, but instead follows its >>>> own implementation in unix.pp in POpen_internal. I am just curious >>>> to know the reason. >>>> >>> Phew, that was over twenty years ago, but afaik the reason is that >>> libc popen and pclose us C FILE descriptors, which the RTL in general >>> doesn't use to avoid a mix of functions with pascal and C file types. >>> >>> So popen/pclose are a more high level (FILE * using) part of libc, >>> while we tend to only use the basis. >> >> Glad our memories agree on this :-) > > Well aside from the fact that FreeBSD was the architecture where the > baseunix/unix RTL? was done. The port to Linux was only done later :-) Correct, but popen/pclose existed before that in the linux unit. Pretty sure about that, because I implemented it there. Michael. From fpc at pascalprogramming.org Mon Jul 20 12:22:37 2026 From: fpc at pascalprogramming.org (Marco van de Voort) Date: Mon, 20 Jul 2026 12:22:37 +0200 Subject: [fpc-pascal] POpen en PClose In-Reply-To: <995cc048-944a-5c4a-1aaf-e798431cb516@freepascal.org> References: <645af5d0-3b91-4176-aa5c-cc02ccd92b96@adriaan.biz> <081cab29-43c5-4180-9e5c-f99420c544b2@pascalprogramming.org> <65e5636b-7e86-221d-87d6-181ea637481c@freepascal.org> <96854e10-aee6-4d6e-bcd7-d2e88cdb90fd@pascalprogramming.org> <995cc048-944a-5c4a-1aaf-e798431cb516@freepascal.org> Message-ID: <401ad6b2-f972-4456-957a-0fad6eb86b2b@pascalprogramming.org> Op 20-7-2026 om 12:07 schreef Michael Van Canneyt via fpc-pascal: >> Well aside from the fact that FreeBSD was the architecture where the >> baseunix/unix RTL? was done. The port to Linux was only done later :-) > > Correct, but popen/pclose existed before that in the linux unit. > Pretty sure about that, because I implemented it there. Yes, I think so.??The left overs of the linux/unix library were done relatively later (first baseunix was done, and everything was migrated),? ?and since the initial libc implementation of baseunix didn't introduce FILE *, it was logical to maintain the signatures. Jonas? might even have started using the libc port for Darwin at that point (IIRC about half an year after the big bang), I can vaguely remember him helping me with some of those leftover? unix functions, which had some issues (iirc clone() usage and problems with a function call that had a deviation way of handling parameters (PIPE?)) .? Darwin and FreeBSD shared quite a lot of pedigree back then. So it could even have been Jonas' decision to maintain the signatures, not mine. From adriaan at adriaan.biz Mon Jul 20 15:13:56 2026 From: adriaan at adriaan.biz (Adriaan van Os) Date: Mon, 20 Jul 2026 13:13:56 +0000 (UTC) Subject: [fpc-pascal] POpen en PClose In-Reply-To: <081cab29-43c5-4180-9e5c-f99420c544b2@pascalprogramming.org> References: <645af5d0-3b91-4176-aa5c-cc02ccd92b96@adriaan.biz> <081cab29-43c5-4180-9e5c-f99420c544b2@pascalprogramming.org> Message-ID: On 20/07/2026 11:40, Marco van de Voort via fpc-pascal wrote: > > Op 20-7-2026 om 10:13 schreef Adriaan van Os via fpc-pascal: >> >> I am looking at the implementation of POpen and PClose in the >> runtime-library for Darwin (or more general for UNIX). It seems like >> it doesn't call into libc popen and pclose, but instead follows its >> own implementation in unix.pp in POpen_internal. I am just curious to >> know the reason. >> > Phew, that was over twenty years ago, but afaik the reason is that > libc popen and pclose us C FILE descriptors, which the RTL in general > doesn't use to avoid a mix of functions with pascal and C file types. > > So popen/pclose are a more high level (FILE * using) part of libc, > while we tend to only use the basis. Ah, so that means that I couldn't just call naively into libc popen with FileRec.Handle ? Regards, Adriaan van Os