Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • executing an external program

    I sometimes send a program to other people. It consists of an ado file that writes out a character file, and a windows .exe file to process that data. The ado file has a line
    Code:
    ! taxsim<`infile' >`outfile'
    to execute the taxsim.exe calculator. By and large my users are unable to follow my instructions to place the executable in the executable path, although they mostly manage to put the ado file in an appropriate place. In some cases this is because IT staff have locked down the executable path directories. I looked at -adosubdir- but don't see how it could be useful - it seems to just reutn the first letter of the filename. Is there a way to put the path to an ado file into a macro? I feel like most of them could put both files in the same place without extreme difficulty. Any other suggestions?

  • #2
    Perhaps you can make use of the findfile command to meet your needs.

    Comment


    • #3
      -findfile- looks like just the right thing to find the executable program my .ado file refers to. -findfile- returns the full path to the named file in `r(fn)", but there is a little problem. Here is an extract from executing the command:

      Code:
      . findfile taxsim27.exe
      \users\hardy27/taxsim27.exe
      Note that while the path returned is nearly correct, there is a "/" (slash) instead of a "" (backslash) before the last component. Windows 10, at least, doesn't find the executable when presented with the command in this form. Indeed the error message from Windows:

      Code:
      '\users\hardy27' is not recognized as an internal or external
      operable program or batch file.
      suggests that Windows stops at the forward slash.

      I suppose a workaround would be to use -subinstr- to edit the path,:

      Code:
      . local x `r(fn)'
      
      . local tmp : subinstr local x "/" "\"
      
      . di "`tmp'"
      \users\hardy27\taxsim27.exe
      but is all that necessary? I feel like the temporary macro tmp shouldn't be necessary.



      This is Stata 15.1 network edition.

      Comment


      • #4
        Have you tried the full path to the exe-file? Something like
        Code:
        c:\users\hardy27/taxsim.exe
        At least under Windows 7, it works. "findfile" should report the full path, at least under Stata 14 it does.

        Comment


        • #5
          Temporary macros are not necessary - just subtle use of inline evlauation of macro expressions. For the following code, since I run macOS which normally uses forward slashes, I demonstrate how to replace a backward slash with a forward slash. For your Windows users you would exchange the two.
          Code:
          . return list
          
          macros:
                           r(fn) : "/bin\date"
          
          . display `" `= subinstr("`r(fn)'","\","/",.)' "'
           /bin/date
          
          . ! `= subinstr("`r(fn)'","\","/",.)'
          
          Wed Dec 11 15:40:50 EST 2019
          Added in note: The reply from Sven-Kristjan Bormann shows superior technique. If that approach does not work for you, you should show the code you use to create your example. I was surprised to see the user's home directory as the location of the executable. My idea was to have the user copy the executable into the same directory as they copy the ado file, presumably a user-writable directory on their ADOPATH.
          Last edited by William Lisowski; 11 Dec 2019, 13:53.

          Comment


          • #6
            I think Lisowski's post confirms the inexplicable use of a forward slash as the separator for the last component of the path is not specific to my installation. Interestingly enough, the mix of forward and backward slashes is evident if I run the -adopath- command There is probably a reason for this behavior that I would possibly not endorse.

            As for Windows behavior, it turns out to be more complicated than I thought. However, it does seem that if you try to execute a command with a full or partial path included rather than just a command name, then the drive letter is required if the separators are mixed. So it is important to specify the adopath with drive letters, and not allow that to default, to avoid the problems with the results of -findfile- that I experienced.

            Comment


            • #7
              There is probably a reason for this behavior ...
              First, it is my understanding that every version of Windows has accepted "/" as a path separator, and every version of MS-DOS beginning with DOS 2.0 (the first version that had subdirectories). It's only been in command lines that "/" was not allowed, because it had already been used as a switch delimiter in MS-DOS 1.0.

              So on Stata commands where it is expecting a path or filename that it will pass to Windows, the direction of the slash is not a problem; Windows will deal with it.

              To explain the behavior reported in post #4, I'd guess that for the Stata shell command, Stata does the user a favor by trying to figure out whether a string containing a forward slash is a Windows path that it needs to clean up, or an arbitrary string, and Stata does so at least in part by looking for a Windows drive letter at the front of the string.

              Remember that Stata suggests using forward slashes in Windows paths since Stata uses the backward slash to escape special characters, which can lead to problems with paths constructed with embedded local macros.

              https://www.stata.com/support/faqs/p...es-and-macros/

              I note that that on a Windows system set up by someone else that I access remotely, the output of the adopath command mimics that of the findfile command, with a forward slash at the end of each directory name. This facilitates building paths up from local macros containing pieces of the path.
              Code:
              . macro list _d1 _d2 _file
              _d1:            ./
              _d2:            .\
              _file:          gnxl.csv
              
              . local df1 `d1'`file'
              
              . local df2 `d2'`file'
              
              . macro list _df1 _df2
              _df1:           ./gnxl.csv
              _df2:           .`file'

              Comment

              Working...
              X