Jump to content
PeterPanettone

Resolve a uses clause unit path?

Recommended Posts

Example: A unit's uses clause contains a unit DSiWin32, for example:

 

image.thumb.png.d3e53e870e1a449c63edbdf30ee5f548.png

 

I know that the unit's file path is:

 

F:\Users\Peter\Documents\Embarcadero\Studio\20.0\CatalogRepository\OmniThreadLibrary_3.07.6-Rio\src\DSiWin32.pas

 

Question: Is there an easy function to extract this path from the Library paths of the current IDE?

 

Example:

MyPath := GetUnitPathFromCurrentLibrary('DSiWin32.pas');

 

Share this post


Link to post

Well, there is a FileSearch function in Sysutils that will search for a file in semicolon-separated list of directory names, but of course you still have to extract the library path from the IDE settings (= registry key, specific for an IDE version), the search path from the current project, if relevant, replace any macros ($(name)) in the pathes etc. to get the list of folders. I'm not aware of a ready-made function for this exposed in the RTL or Open Tools API.

 

Share this post


Link to post
Guest

I would state my goal if i were you. I do not know an iota about OTA.

Still your first post confuses me. Is it relevant outside of OTA? Do you want it Designtime or Runtime?

The pseudocode looks like you somehow want the deployed app to execute that line. Wierd.

And why post in Win API subgroup. Do Windows even care about Dephi units?

I will prolly not being the one helping you, but if you want any input of quality IMHO you should provide more info regarding your task.

 

HTH

Share this post


Link to post
On 8/19/2019 at 2:49 AM, PeterPanettone said:

Is there an easy function to extract this path from the Library paths of the current IDE?

"Easy" can be subjective 🙂 You'd need to have both the IDE search paths *and* the project paths.

 

For the first, you could read the values from Search Path value for the appropriate platform in the Library subkey in the registry.

 

For the second, you could obtain an IOTABuildConfiguration (for the relevant config) from the IOTAProjectOptionsConfigurations for the active project, and call GetValues for sUnitSearchPath (from DCCStrs).

 

You'd also need to expand any macros in the paths. Then, starting from the project paths first, check each path (in order) for existence of the file.

 

I think they have code for retrieving the paths somewhere inside CnWizards: https://github.com/cnpack/cnwizards

 

Edited by Dave Nottage
  • Like 1

Share this post


Link to post
29 minutes ago, Dave Nottage said:

I think they have code for retrieving the paths somewhere inside CnWizards: https://github.com/cnpack/cnwizards

Likely so, but whether it is interwoven with other modules is an open question. I have looked in there before, and too often found things which would be nice to borrow, but hard to mine.

Edited by Bill Meyer

Share this post


Link to post

I sometimes miss the output from the old compilers which showed the path and name of  the units being compiled in the sequence they were built, in a complete log.

  • Like 2

Share this post


Link to post
On 8/20/2019 at 4:25 PM, Ondrej Kelle said:

Some pointers can also be found here.

Thanks for the link! Pretty much describes what I said 🙂

 

Share this post


Link to post

I know I'm a week behind in this conversation but unfortunately the code @Dave Nottage referred to does not work.

I've had to do something similar today for an old OTA plug-in in which I never checked for CodeSiteLogging being on the library path. The below code is what I've eventually had to do (`IOTAProjectOptionsConfiguration` would not return any useful information on the project).

Class Procedure TDDTOpenToolsAPIFunctions.CheckLibraryPath;

ResourceString
  strCodeSiteLoggingNotFound = '"CodeSiteLogging" not found in your library paths!';

Const
  strProjectSrcDir = 'SrcDir';
  strDCCLibraryPath = 'LibraryPath';
  strCodeSiteLoggingDcu = 'CodeSiteLogging.dcu';

Var
  slSearchLibrary: TStringList;
  PO: IOTAProjectOptions;
  S : IOTAServices;
  BDSMacros: TRegEx;
  M: TMatch;
  slMacros: TStringList;
  iMacro: Integer;

Begin
  slSearchLibrary := TStringList.Create;
  Try
    If Supports(ActiveProject.ProjectOptions, IOTAProjectOptions, PO) Then
      slSearchLibrary.Add(StringReplace(VarToStr(PO.Values[strProjectSrcDir]), ';', #13#10, [rfReplaceAll]));
    If Supports(BorlandIDEServices, IOTAServices, S) Then
      slSearchLibrary.Add(StringReplace(VarToStr(S.GetEnvironmentOptions.Values[strDCCLibraryPath]), ';', #13#10, [rfReplaceAll]));
    slMacros := TStringList.Create;
    Try
      BDSMacros := TRegEx.Create('\$\((\w+)\)', [roIgnoreCase, roMultiLine, roCompiled]);
      For M In BDSMacros.Matches(slSearchLibrary.Text) Do
        Begin
          If slMacros.IndexOfName(M.Groups.Item[1].Value) = -1 Then
            slMacros.AddPair(M.Groups.Item[1].Value, StringReplace(
              GetEnvironmentVariable(M.Groups.Item[1].Value), '\', '\\', [rfReplaceAll]));
        End;
      For iMacro := 0 To slMacros.Count - 1 Do
        Begin
          BDSMacros := TRegEx.Create('\$\(' + slMacros.Names[iMacro] + '\)', [roIgnoreCase, roMultiLine, roCompiled]);
          slSearchLibrary.Text := BDSMacros.Replace(slSearchLibrary.Text, slMacros.ValueFromIndex[iMacro]);
        End;
    Finally
      slMacros.Free;
    End;
    If FileSearch(strCodeSiteLoggingDcu, StringReplace(slSearchLibrary.Text, #13#10, ';',
      [rfReplaceAll])).Length = 0 Then
      OutputMsg(strCodeSiteLoggingNotFound);
  Finally
    slSearchLibrary.Free;
  End;
End;

 

Edited by David Hoyle

Share this post


Link to post
Guest
25 minutes ago, David Hoyle said:

unfortunately the code @Dave Nottage referred to does not work.

I'm not surprised - it's 10 years old. 😉

Share this post


Link to post

Actually I disagree, sorry.

The IOTABuildConfiguration should be the new way to do thing as its takes account of the various configurations you might want (Debug / Release being the basics).

I used IOTAProjectOptions which is the old pre-XE2 IDE style where there was only one option but it does seem to return the active configuration which is what I wanted.

I got 4 values out of the active IOTABuildConfiguration but loads of stuff out of the IOTAProjectOptions and I could use any of the constants in DCCStrs or CommonOptionsStrs.

BTW: I'm using 10.2.3. I have yet to test this on previous compilers / IDEs.

Share this post


Link to post

Are you aware of this function from IOTAServices?

 

    { ExpandRootMacro will change a string that contains $(BDS) or any $(name)
      and expands that environment variable. So for example $(BDS)\bin will be
      expanded to C:\Program Files\Embarcadero\10.0\bin assuming that
      BDS=C:\Program Files\Embarcadero\10.0 }
    function ExpandRootMacro(const S: string): string;

 

Share this post


Link to post

@Uwe Raabe No I wasn't 😞 Can't remember when environment variables were introduced but I see that start life in XE3. I would have to test whether this works for all environment variables, i.e. %AppData% etc.

Share this post


Link to post
Guest
1 hour ago, David Hoyle said:

Actually I disagree, sorry.

I apologise, no flame intended 🙂 Was that a reply to me? It's not terribly important - but do you disagree with the fact that the code was posted in 2009? 🙂

Just curious. I wish you a nice Sunday. 🙂

Share this post


Link to post

No flame was inferred 😀. The point I was trying to make was that Dave suggested using iOTABuildConfiguration with constants. This would not work for me.

Share this post


Link to post

Couldn't see the wood for the trees yesterday...

If Supports(Project.ProjectOptions, IOTAProjectOptionsConfigurations, POC) Then
  Begin
    strSearchPath := POC.ActiveConfiguration.Value[sUnitSearchPath];
    ...
  End;

That's been bugging me all day (pun intended) 🙂

Share this post


Link to post
On 8/25/2019 at 11:41 PM, David Hoyle said:

the code @Dave Nottage referred to does not work.

Which part? In any event, I use them successfully in my own experts.

Edited by Dave Nottage

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×