Nothing Special   »   [go: up one dir, main page]

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot parse rtl\sys\System.Types.pas #171

Open
andre2007 opened this issue Jan 5, 2023 · 5 comments
Open

Cannot parse rtl\sys\System.Types.pas #171

andre2007 opened this issue Jan 5, 2023 · 5 comments

Comments

@andre2007
Copy link
Contributor
andre2007 commented Jan 5, 2023

I try to parse file System.Types.pas on Windows 11 using this command
pasdoc --format simplexml --output output "C:\Program Files (x86)\Embarcadero\Studio\19.0\source\rtl\sys\System.Types.pas"

Following infos and warnings are shown:

Info[1]:    Starting Source File Parsing ...
Info[2]:    Now parsing file C:\Program Files (x86)\Embarcadero\Studio\19.0\source\rtl\sys\System.Types.pas...
Warning[2]: Cannot evaluate this $if / $elseif condition, assuming that "( defined(IOS) and not defined(CPUARM) and defined(EXTERNALLINKER))" is true. Error message is: Expected identifier (function name), got symbol "("
Warning[2]: Error EPasDoc: C:\Program Files (x86)\Embarcadero\Studio\19.0\source\rtl\sys\System.Types.pas(1138): One of symbols "," or ":" expected while parsing unit System.Types.pas, continuing...
Info[2]:    ... 1 Source File(s) parsed
Fatal Error: EPasDoc: At least one unit must have been successfully parsed to write docs

No xml is created. How can I get the XML output for this unit?

@andre2007 andre2007 changed the title Cannot parse rtl\sys\System.SysUtils.pas Cannot parse rtl\sys\System.Types.pas Jan 6, 2023
@Fr0sT-Brutal
Copy link
Collaborator
Fr0sT-Brutal commented Jan 9, 2023

PasDoc's ability to parse and evaluate compiler defines are quite simple and limited so such complex conditions could likely behave weird.

Anyway, how could we know what the issue is without failing source fragment?

@andre2007
Copy link
Contributor Author

Yes, I see. In the System units there are a lot of compiler directives. It seems rather impossible to find out what exactly causes the issue. Thanks, I will close this incident.

@michaliskambi
Copy link
Collaborator

Tl;dr: I have reproduced the issue and made a small testcase, attaching.

nested_rec.pas.txt

Longer version:

As I had access to Delphi 11, I could reproduce the fail. It's a bit different Delphi version and different line number, but looks similar enough to suspect that it's the same culprit.

And it is not related to $if / $elseif expressions.

I experienced this fail:

$ cd ..../Embarcadero/Studio/22.0/source/rtl/sys
$ pasdoc System.Types.pas
...
Info[1]:    Starting Source File Parsing ...
Info[2]:    Now parsing file System.Types.pas...
Warning[2]: Cannot evaluate this $if / $elseif condition, assuming that "( defined(IOS) and not defined(CPUARM) and defined(EXTERNALLINKER))" is true. Error message is: Expected identifier (function name), got symbol "("
Warning[2]: Cannot evaluate this $if / $elseif condition, assuming that "SizeOf(LongWord) = SizeOf(Cardinal)" is true. Error message is: Evaluating "sizeof" function for $if / $elseif not implemented
Warning[2]: Cannot evaluate this $if / $elseif condition, assuming that "SizeOf(LongWord) = SizeOf(UInt64)" is true. Error message is: Evaluating "sizeof" function for $if / $elseif not implemented
Warning[2]: Error EPasDoc: System.Types.pas(1167): One of symbols "," or ":" expected while parsing unit System.Types.pas, continuing...
Info[2]:    ... 1 Source File(s) parsed
Fatal Error: EPasDoc: At least one unit must have been successfully parsed to write docs

Looking at the faulty line of code (1167), PasDoc fails to process a nested record in a peculiar case. Playing around, I was able to cut it down to trivial testcase, that is also hopefully so small and meaningless that publishing it here falls under "fair use" and doesn't make problems because of Delphi copyright.

I'm attaching it here, and reopening this issue. This is valid issue, and now we have a reproduction, and when someone will find time -- it should be fixed in (likely in PasDoc_Parser.pas).

@Fr0sT-Brutal Please let's be a bit more encouraging to users who submit bugreports.

  • Let's try to do better and provide constructive pointers how to send us a reproducible testcase.

  • And also let's recognize that this bugreport was about a Delphi source code, which isn't really that straightforward, because you cannot just upload Delphi source code publicly (it's copyrighted by Embarcadero). And if in doubt -- pointing us to it is indeed safest, like the report did.

Just as an example for next time, a better answer would be like this:

"""

  • Please cut down the source code that fails to a small reproducible testcase. We may not have access to Delphi source code (and this particular Delphi version).

  • Take a look at the line indicated in your bugreport, System.Types.pas(1138): One of symbols "," or ":" expected while parsing unit . This line likely points to the problematic construct, and everything else in that unit can be removed, while still showing the error.

  • Since this is a copyrighted code, from Embarcadero, be especially careful with sharing it. Don't just upload the unit here. Make sure to really cut it down to the bare minimum, preferably a really useless non-functional minimum but one that still demonstrates the problem, such that it falls under "fair use". If you're unsure, just point us to the file and/or describe the problem with words.
    """

@michaliskambi michaliskambi reopened this Jan 13, 2023
@andre2007
Copy link
Contributor Author

I just wonder whether this issue can be solved with the Delphi compiler. Let me explain. In the programming language C there is something called preprocessor. This tool evaluates all the directives (#if, #define) and outputs the resulting pure C code.
I wonder whether there is something similiar for Delphi? Then I could just pre process the unit before passing it to Pasdoc.

@michaliskambi
Copy link
Collaborator

I just wonder whether this issue can be solved with the Delphi compiler. Let me explain. In the programming language C there is something called preprocessor. This tool evaluates all the directives (#if, #define) and outputs the resulting pure C code.
I wonder whether there is something similiar for Delphi? Then I could just pre process the unit before passing it to Pasdoc.

It would indeed be nice if Delphi or FPC included something that acts "just as a preprocessor", similar to C language cpp ( https://gcc.gnu.org/onlinedocs/cpp/Overview.html#Overview ). However I'm not aware of such thing.

Related: We actually provide such preprocessor as part of PasDoc :) Our tool pascal_pre_proc (source/tools/pascal_pre_proc.dpr) was created exactly to fill this need. As an input, it takes a Pascal code with directives like {$ifdef xxx}, as an output it produces Pascal file with such directives evaluated and removed.

See https://pasdoc.github.io/OtherTools .

Alas, as you probably guess, pascal_pre_proc.dpr shares the same code, so same limitations, as regular PasDoc. So it will fail to process some $if statements that Delphi / FPC can process OK.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants