English Amiga Board


Go Back   English Amiga Board > Support > support.Other

 
 
Thread Tools
Old 10 November 2016, 11:16   #21
Pheonix
Registered User
 
Join Date: Aug 2009
Location: Waco USA
Posts: 253
LFORMAT in List is extremely limited in 1.3 The only variable that works is %s. By using multiples I can get it to include the path (so %s%s would be Path/filename.) But that is all I can't even get it to list all "except" .info files. In 2+ you can go "List ~(#?.info) and it would list all non-info files. But not in 1.3.

I've pretty much given up on just using a normal CLI script to do it. I'm currently building an Arexx script to do it. The basic script I've written just takes the stored output from a list command and strips the .info off the end of every line. That's up & running just fine. Not as neat & tidy as I'd like, but it works. It also strips out .info files for directories (yes a bug I saw coming in advance.)

Right now, I'm attempting to put more into the script itself so I can eliminate as many commands from my Startup-Sequence as I can. Basically, getting Arexx to do everything itself instead of doing a list, then Arexx, then execute, then Cleanup.

So, first step, create the script to dig through the .info files and eliminate the directory icons (.info being the main one.) Then do a WBLoad for each icon with the .info stripped off the end. The only issue being that Arexx only has one command to get a directory listing. ShowDir() doesn't allow filters except to limit it to files or directories. So I can't use a wildcard filter to just pull up the .info files.

Once that's done, I'm considering adding in an improvement. WB 2.x will error out if there are any directories in WBStartup, and WB 3.x will just ignore them (though it does seem to slow bootup if there are any there.) I'm considering setting it up so that it will parse the contents of directories as well. Though that could lead to a rather complex script. I'm still looking at that.
Pheonix is offline  
Old 10 November 2016, 12:35   #22
Daedalus
Registered User
 
Daedalus's Avatar
 
Join Date: Jun 2009
Location: Dublin, then Glasgow
Posts: 6,334
Yeah, that's pretty limiting alright. ARexx is a good alternative if you have ARexx installed, and gives you all the flexibility you'll need.

ARexx supports procedures with local variables, so using them makes it easy to recurse into subdirectories to any depth - memory and stack permitting. Just use a procedure to scan the directory and to call itself when it discovers another directory. As for filtering, it's not that big a deal to do it manually since you'll have the whole directory listing there anyway.

Pseudocode:

Code:
ScanDrawer(SYS:WBStartup)
End

Procedure ScanDrawer(drawer)
  For each item in drawer
    If item is drawer
      ScanDrawer(item)
    Else
      If right(item, 5) = ".info"
        MyProg = left(item, len(item) - 5)
        If MyProg is not drawer
          WBRun MyProg
        End If
      End If
    End If
  Next
End procedure
My ARexx is a little rusty and I'm not at home so I don't wanna post code that's only 90% right
Daedalus is offline  
Old 10 November 2016, 13:56   #23
idrougge
Registered User
 
Join Date: Sep 2007
Location: Stockholm
Posts: 4,332
Code:
IF ~AddLib("rexxsupport.library",0,-30,0) THEN EXIT 20
files=ShowDir(dir,'FILES','ÿ')
DO while files~=''
  PARSE VAR files filename 'ÿ' files
  IF Right(filename,5)=='.info' THEN ADDRESS 'COMMAND' 'WBrun' filename
  END
idrougge is offline  
Old 10 November 2016, 14:03   #24
Pheonix
Registered User
 
Join Date: Aug 2009
Location: Waco USA
Posts: 253
Actually just finished up the script, tested and working. Including it here

Code:
/* WBStartup Script */


if Arg() ~= 1 then exit

if Show('L',"rexxsupport.library")
   then LLoad = 0
   else if AddLib("rexxsupport.library",0,-30,0)
         then LLoad = 1
         else DO
            say "Cannot load rexxsupport.library"
            exit
            END

dstart = Arg(1)

flist = ShowDir(dstart,'f')
fcount = Words(flist)

if fcount > 0
   then DO X=1 to fcount

      cfile = Word(flist,X)
      clength = Length(cfile)

      if clength < 6
         then Iterate X

      if Compare(Upper(SubStr(cfile,(clength-4))),".INFO") ~= 0
         then Iterate X

      Open(in,dstart"/"cfile,read)
      Seek(in,48,'B')
      T = C2D(ReadCh(in,1))
      Close(in)

      if T == 2
         then Iterate X

      Address COMMAND WBLoad dstart"/"SubStr(cfile,1,(clength-5))

      END

dlist = ShowDir(dstart,'d')
dcount = Words(dlist)

if dcount > 0
   then DO X=1 to dcount
      Address COMMAND "rx WBStart "dstart"/"Word(dlist,X)
      END

if LLoad == 1
   then RemLib("rexxsupport.library")

Exit
I set the script up so that the directory it scans is passed to it as a command line argument "Arg(1)". That way, I can call the script again for every directory it encounters. I imagine that how deep it can go depends on the available RAM. I have 8 meg fast RAM and 2 meg chip RAM on my system, so I imagine it could go fairly deep.

I also follow standard cleanup procedures. If I load or open something, then I unload or close it when I'm done. The only thing I didn't worry about is "DROP"ing variables when I was done with them. That could actually shave some RAM and extend the depth a bit, but I don't see how it would make a difference.

With a bit of work, I can set it up so that multiple drawers can be passed at one time. I also should set it up to make sure a drawer actually exists as well, but it works for now - I'll tweak & clean it later.
Pheonix is offline  
Old 10 November 2016, 14:11   #25
Pheonix
Registered User
 
Join Date: Aug 2009
Location: Waco USA
Posts: 253
idrougge:

Your response came while I was typing I messed with Parse for a bit, but found it easier to just use the Words() & Word() functions. Though I need to check & see how it will handle files with spaces in the name. A file "Run Me.info" could end up breaking down to "Run" which would be skipped both by size & lack of ".info" and "Me.info" which would break down to "WBLoad Me" which would result in not being found.

If you haven't guessed, I learned most of my programming in MS-DOS, and spaces in file names couldn't exist.
Pheonix is offline  
Old 10 November 2016, 14:29   #26
Pheonix
Registered User
 
Join Date: Aug 2009
Location: Waco USA
Posts: 253
Well, non-existent drawers isn't an issue, and I put in a fix for non-existent files.

However, files with spaces is a problem. The main fix for that is to put in a specific specific separator that is illegal in a file name (like '/') and then use another method to parse it out.

Working.....
Pheonix is offline  
Old 10 November 2016, 15:14   #27
Daedalus
Registered User
 
Daedalus's Avatar
 
Join Date: Jun 2009
Location: Dublin, then Glasgow
Posts: 6,334
You can just tag quotes onto either side of the filename argument to deal with spaces and non-spaces without caring. ARexx lets you use single quote and double quote pairings interchangeably, so quotes can be included in a string. For example:

Address COMMAND WBLoad '"'||dstart||'/'||SubStr(cfile,1,(clength-5))||'"'

should work (though I haven't tested it), and should result in the WBLoad argument being enclosed entirely in quotes which will take of spaces.


Instead of recursing by launching new ARexx scripts, why not just use a procedure and keep it all in the one script? That should speed things up a little as well as using less RAM by not spawning a new process for each new drawer found.
Daedalus is offline  
Old 10 November 2016, 15:18   #28
Pheonix
Registered User
 
Join Date: Aug 2009
Location: Waco USA
Posts: 253
OK, got it fixed Corrected script below. It now handles files & directories with spaces in the name.

Code:
/* WBStartup Script */

if Arg() ~= 1 then exit

if Show('L',"rexxsupport.library")
   then LLoad = 0
   else if AddLib("rexxsupport.library",0,-30,0)
         then LLoad = 1
         else DO
            say "Cannot load rexxsupport.library"
            exit
            END

dstart = Arg(1)

flist = ShowDir(dstart,'f','/')

DO FOREVER

      if Compare(flist,'') == 0 then Leave

      cmark = Index(flist,'/')

      if cmark = 0
         then DO
            cfile = flist
            flist = ''
            END
         else DO
            cfile = Left(flist,(cmark-1))
            flist = DelStr(flist,1,cmark)
            END

      clength = Length(cfile)

      if clength < 6
         then Iterate

      if Compare(Upper(SubStr(cfile,(clength-4))),".INFO") ~= 0
         then Iterate

      if ~Open(in,dstart"/"cfile,read)
         then Iterate

      Seek(in,48,'B')
      T = C2D(ReadCh(in,1))
      Close(in)

      if T == 2
         then Iterate

      Address COMMAND WBLoad '"'dstart'/'SubStr(cfile,1,(clength-5))'"'

      END

flist = ShowDir(dstart,'d','/')

DO FOREVER

   if Compare(flist,'') = 0 then Leave

   cmark = Index(flist,'/')

   if cmark = 0
      then DO
         cfile = flist
         flist = ''
         END
      else DO
         cfile = Left(flist,(cmark-1))
         flist = DelStr(flist,1,cmark)
         END

   Address COMMAND rx "WBStart "dstart"/"cfile

   END

if LLoad == 1
   then DO
      RemLib("rexxsupport.library")
      Address COMMAND sound "CH0:s/Start.iff v64 q"
      END

Exit
Pheonix is offline  
Old 10 November 2016, 15:38   #29
Pheonix
Registered User
 
Join Date: Aug 2009
Location: Waco USA
Posts: 253
Quote:
Originally Posted by Daedalus View Post
You can just tag quotes onto either side of the filename argument to deal with spaces and non-spaces without caring. ARexx lets you use single quote and double quote pairings interchangeably, so quotes can be included in a string. For example:

Address COMMAND WBLoad '"'||dstart||'/'||SubStr(cfile,1,(clength-5))||'"'

should work (though I haven't tested it), and should result in the WBLoad argument being enclosed entirely in quotes which will take of spaces.


Instead of recursing by launching new ARexx scripts, why not just use a procedure and keep it all in the one script? That should speed things up a little as well as using less RAM by not spawning a new process for each new drawer found.
Again, a post while I was typing

Throwing quotes around the file name was necessary, and I added that in. The problem was when parsing with Words() & Word() it uses spaces to mark out the words. So, in the original script a file named "This is a Test.info" would parse out to cfile becoming "This" on one loop, "is" on the next, then "a" then "Test.info". It counts it as 4 separate words.

Make the ShowDir return files with '/' (an illegal character for file names,) I can then create a cfile value of "This is a Test.info" by looking for the '/' character in the list.

I would have to do some testing, but in most cases you would be able to go deeper into sub directories by depending on system RAM (even including the overhead,) than by a standard stack size. Also, when I first started reading on Arexx scripts, it was implied that all variables are global in scope. So, when I read the list of directories into flist (dlist originally,) and call the procedure, then I read the new directory it would replace the variable that I'm already using. I can push the old one at the beginning, then pull it back out before the end, but again, that's even more stack space being taken up.

It was a judgement call, really. It should work either way. I would really need to build an extremely deep directory structure and test to see what happens if you overload things to see which is actually better in the long run. I guess that's my next project for this, figuring out how to limit directory diving to prevent out of memory issues.
Pheonix is offline  
Old 10 November 2016, 16:48   #30
Daedalus
Registered User
 
Daedalus's Avatar
 
Join Date: Jun 2009
Location: Dublin, then Glasgow
Posts: 6,334
Oops, sorry

Ah, I get what you're saying regarding the words separated by spaces. I remembered (incorrectly) that ShowDir returned the stem of an array containing all the entries, so flist.1 was the first entry, flist.2 was the second and so on.

True, it should work both ways, and I would imagine it's extremely unlikely that a directory structure would be so deep that it makes a real difference either way. Variables can be local to procedures though - you have to explicitly expose them from a procedure to make them global. Outside that though, all variables are global since there's no namespace or anything like that in a script.
Daedalus is offline  
Old 10 November 2016, 22:22   #31
Pheonix
Registered User
 
Join Date: Aug 2009
Location: Waco USA
Posts: 253
I went ahead and built 2 versions of the script. One that creates a new process every time it scans another directory, and one that uses a function (Procedure) that calls itself for each new directory. I also added in code that would allow multiple directories to be given on the command line. Makes it useful more more than just a WBStartup directory

I've attached them as text files as they are rather lengthy. They have MS-DOS style linefeed + carriage return (/n/r) line terminators, so they'll end up double spaced on most classic Amiga systems unless you run them through a filter first.

The code should be forgiving of non-existent directories & files. Though the latter shouldn't be an issue any more. To use either one to implement a WBStartup directory in Workbench 1.3, just place it in your REXX: directory and rename it to a .rexx file (such as WBStartup.rexx) Then add the line "rx WBStartup SYS:WBStartup" to your startup Sequence, after Arexx (rexxmast) and Workbench (LoadWB) have been started. You will also need to put WBLoad (Can be found in the CLICon package,) somewhere in the path.

Theoretically, WBRun can do the same thing, but I can't get it working, so I can't test it.
Attached Files
File Type: txt Function.txt (2.2 KB, 113 views)
File Type: txt Process.txt (2.3 KB, 97 views)
Pheonix is offline  
Old 11 November 2016, 00:46   #32
idrougge
Registered User
 
Join Date: Sep 2007
Location: Stockholm
Posts: 4,332
You don't need ADDRESS COMMAND RX… to launch an ARexx script. If it's on your path, just call it as if it was an internal function.

In other words, the line "CALL Script argument" causes the ARexx interpreter to look for a procedure called Script in this order:
1. Inside the file
2. Built-in in ARexx
3. In any loaded ARexx command library or function host (such as rexxsupport.library)
4. In the path or current directory.

So if you have a file called Script.rexx in your path, "CALL Script" will call it just as if it was an procedure inside your program.
idrougge is offline  
Old 11 November 2016, 02:58   #33
Pheonix
Registered User
 
Join Date: Aug 2009
Location: Waco USA
Posts: 253
The idea was to create it in a separate memory space. If it's called in that manner, it acts the same as the function call (the other script.) I'm not sure, exactly, how the Amiga apportions RAM in these cases, though. To really measure it, I would need to set up a script running in the background, then do a memory dump to see what sort of RAM footprint it generates.

From the other machines I've worked on, that footprint would mark the absolute limit of a function based nest. Whereas a process based nest would, instead, repeat the footprint over and over. So, if the script (when started,) generated a 64k footprint (generally 4k of which is stack,) then when that 64k is filled with the growing variable list, or the stack is filled with stored arguments & return points, the program crashes. Or, in the case of a process based nest, the 64k processes fill up the currently available RAM blocks, it again crashes.

Which is faster? The function based, more than likely. Which has more room to grow? Most likely the process based. The core reason for creating it doesn't need that much room to grow, so I am currently using the function based script. But I tend to try and write things for expand-ability. Being able to use it for things other than its original purpose.

So, the next step would be to add in a way to apply a different command other than WBLoad. Also add in ways to tell it what to work with other than just .info files. Maybe tell it "not" to go into sub-directories. Not going to add in any other real functionality, though. Just go through and process all files of a single type in a directory with a specific command. When parsing the argument, just make the first one the command that will be used (WBLoad in this case.) The second would be a string (wild card enabled,) to say which files to work on. Finally, an optional switch that will turn off scanning sub-directories. Though, now that I've typed this far, it also occurs to me, that if .info files are the target, a way to say "don't" work on certain types of files either. WBLoad generates an error if you point it to a directory icon, for example, which cancels the script.

That's all tomorrows problem though I'm just now learning programing on the Amiga. Arexx is a nice first step. May dig into Basic later. May skip straight to C or C++, which is what I use on the PC (my modern system.) It's backwards, I know, I started learning different systems in the order I owned them. Except for the Amiga I skipped the Amiga and went to the PC. Now I'm circling back to the Amiga.

Once I get both of them up and running fully (only the 2000 is fully functional,) I'll have access to all 3 generations of classic OS (1.3, 2.1, & 3.9.) All I really need for my 4000 is a scandoubler/flickerfixer. Though a working RTG would be nice. I spent a small fortune (based on my income,) on a Picasso IV, only to discover that it doesn't work completely (when I could finally start testing it.) Really wish I could track down "exactly" what the problem is with it (and fix it.) But even the designer (I think they said that's who they were,) couldn't pinpoint the exact culprit From my research, that was the perfect solution. No external switch boxes, full AGA capable flickerfixer & scandoubler, and pretty decent RTG graphics as well.
Pheonix is offline  
Old 11 November 2016, 13:43   #34
daxb
Registered User
 
Join Date: Oct 2009
Location: Germany
Posts: 3,303
I would use PARSE VAR... instead of WORD(), WORDS() as already suggested. Its faster/better. Using SHOWDIR() with a seperator use '0a'x like it is mentioned in ARexx.guide. REMLIB() only removes the name of a lib from the list, not from memory. At least in this case it doesn`t make sense using it.

Why recursive? You don`t need it for WBStartup (and isn`t supported by later OS as you wrote already), so avoid it.

Have a look at other ARexx libraries like rexxtricks.library, rexxarplib.library to make live easier.

This is an example from Thomas that lists files/dirs from a given path (here SYS: ) with max depth (tiefe):
Code:
/* rexx */

if ~show('L', "rexxsupport.library") then
        if ~addlib('rexxsupport.library', 0, -30,0) then
                exit 10

max = 9
call list_dir 0,"SYS:"
exit


list_dir: procedure expose max
        tiefe = arg(1)
        pfad = arg(2)

        liste = showdir(pfad,"D",'0a'x)
        do while (liste ~= "")
                parse var liste name '0a'x liste
                say left("",3*tiefe)left(name,20) "(Verzeichnis)"
                if tiefe < max then
                        call list_dir tiefe+1,AddPart(pfad,name)
                else
                        say left("",3*tiefe+3)"** Maximaltiefe erreicht **"
        end

        liste = showdir(pfad,"F",'0a'x)
        do while (liste ~= "")
                parse var liste name '0a'x liste
                say left("",3*tiefe)left(name,20) "(Datei)"
        end
return


AddPart: procedure
        a1 = arg(1)
        a2 = arg(2)

        if a1 = "" then
                return a2

        x = right(a1,1)
        if x = "/" | x = ":" then
                return a1||a2
        else
                return a1"/"a2
Here an example that uses FileList() from rexxarplib.library instead of SHOWDIR() with a subdir switch but without max depth:
Code:
/* 
 * Uses FileList() from rexxarplib.library V3.8
*/

subdirs = 1   /* 1 = scan subdirs. 0 = no subdirs */

list = GetFilelist(path, '*.syx')   /* ARG1 = path, ARG2 = wildcards (at least one '*' is needed) */

EXIT

ListFiles: PROCEDURE EXPOSE wildcards list
path = ARG(1)
numFiles = FileList(path || wildcards, myFileList, F, E)
DO i = 1 TO numFiles
    list = list || myFileList.i || '0A'x
END
RETURN list

ScanSubdirs: PROCEDURE EXPOSE wildcards list
path = ARG(1)
numDirs = FileList(path ||'*', myDirList, D, E)
DO i = 1 TO numDirs
    CALL ScanSubdirs(myDirList.i ||'/')
END
CALL ListFiles(path)
RETURN list

GetFilelist: PROCEDURE EXPOSE subdirs
path = ARG(1)
wildcards = ARG(2)
list = ''
IF subdirs = 1 THEN DO
    list = ScanSubdirs(path)
END
ELSE DO
    list = ListFiles(path)
END
RETURN list
daxb is offline  
Old 11 November 2016, 22:35   #35
Pheonix
Registered User
 
Join Date: Aug 2009
Location: Waco USA
Posts: 253
If all I was wanting was the same functionality as OS 2+, I would have stopped with the first version. Which only took the non-directory .info files in SYS:WBStartup and cycled them through WBLoad. I reached my first goal within an hour of actually working with Arexx. It wasn't pretty, but it got the job done.

I then decided to expand functionality, primarily as a means of teaching myself Arexx programming. That's what I've been doing so far. My code is not optimized, because of my self-teaching method. I take what I want a piece of code to do, I research how to do it, the first method I come across that works is what I use, then I move to the next target. After the project is completed and working as planned, I start looking for ways to streamline & optimize the code. It's one of the reasons I tend to write short modules instead of one long program.

Right now, I'm at the optimization phase. I start looking for quicker, cleaner, shorter ways of doing things and making the changes. Once I'm satisfied with this, I might expand the functionality even more as mentioned in a previous post. I might also, at that time, do a complete re-write as well. I'm not going to push it to do everything, but allowing me to specify the command used (instead of just WBLoad,) turn on/off scanning sub-directories, and specifying the directory(s) to scan is about the limit for this particular project before I move on to either another language, or a more ambitious Arexx script.

I didn't actually set out to start learning Amiga programming. I just wanted a way to start a cosmetic change program during startup without locking the CLI console so it won't close. In the process of finding WBLoad, a comment from Daedalus had me wanting to set up a WBStartup directory, and things went from there.

Finally, yes, it may not be necessary to remove rexxsupport.library from the table, but that is just standard cleanup methodology for me. If you load it, unload it. If you open it, close it. It doesn't matter if it doesn't free up much (or any) RAM, or if the environment will take care of it for you. It's just a good habit to be in. On the few complex programs I've written (and not just adapted,) I try to create a function that's just cleanup. Whenever I load/open something that isn't going to be unloaded/closed in short order, I'll go to the cleanup function and add in a check to take care of it in case it hadn't been done.

Updated scripts with some optimization:
Attached Files
File Type: txt Function.txt (1.7 KB, 103 views)
File Type: txt Process.txt (1.7 KB, 108 views)
Pheonix is offline  
Old 12 November 2016, 10:53   #36
Pheonix
Registered User
 
Join Date: Aug 2009
Location: Waco USA
Posts: 253
Well, I think I have it finalized. When I started adding functionality, I noticed a marked difference between function based nesting and process based nesting, with function based being considerably faster. So, I've dropped the process based nesting. You'd really need to have a rather deep directory tree for it to make a real difference there anyways. Also, since the primary purpose of it is to start up everything in a WBStartup style directory, it isn't likely to need something that deep.

As the final version (other than optimization & tweaks,) I've set it to default to not scanning sub-directories. I've also set it up to require a command be provided, in case a different program other than WBLoad is to be used. So, the first argument must be the command that will be used to process all the Icons in whatever directory is provided. The rest of the arguments are the directory (or directories,) to be scanned. You can also provide -s (or -S) as an argument to indicate that sub-directories are to be scanned as well.

Can't really think of anything else to add without straying too far away from the original purpose. So, for now, it seems I'm finished with this. Time for another project The code is below, if anyone wants to take a look or use it. It will require Arexx be installed (I have v1.5, don't know how other versions will react.) It will also need a program that processes Icon files as if double-clicked from workbench (such as WBRun or WBLoad.) I can't comment on how they will react with the script other than WBLoad (comes with CLICon.lha on aminet,) as I couldn't get WBRun to work

:EDIT: Came across a minor error in the script I missed. Also did a little more tweaking. Can now specify a maximum scan depth if sub-directory scanning is turned on. Just add a number after the -s (-s3 would only scan 3 sub-directories deep, for example.)
Attached Files
File Type: txt WBStart.txt (2.6 KB, 103 views)

Last edited by Pheonix; 12 November 2016 at 16:02. Reason: Correcting missed error in file.
Pheonix is offline  
Old 13 November 2016, 04:13   #37
idrougge
Registered User
 
Join Date: Sep 2007
Location: Stockholm
Posts: 4,332
Quote:
Originally Posted by Pheonix View Post
Finally, yes, it may not be necessary to remove rexxsupport.library from the table, but that is just standard cleanup methodology for me. If you load it, unload it. If you open it, close it. It doesn't matter if it doesn't free up much (or any) RAM, or if the environment will take care of it for you. It's just a good habit to be in. On the few complex programs I've written (and not just adapted,) I try to create a function that's just cleanup. Whenever I load/open something that isn't going to be unloaded/closed in short order, I'll go to the cleanup function and add in a check to take care of it in case it hadn't been done.
Removing resources in ARexx is generally an anti-pattern. The interpreter will always close files for you upon exit, and the OS will take care of flushing libraries. If you're recursively calling your own script, removing and then adding a library is just overhead.

I understand the notion of wanting to make a thorough cleanup, but you should also adapt your method to the environment at hand. Closing a file that is going to be closed anyway is just a way to make your program slower and more convoluted; the Close() function is there not for cleanup, but for those cases when you're sharing your file with other programs or handling several files at once — or, as in your script, reusing the same file handle for different files.

So, in short, if you're going to optimise, remove needless cleanup, since interpreting your cleanup commands is always going to be slower than leaving it to the interpreter to do it at leisure.

Oh, and you shouldn't worry about stack. The directory depth of a file system is much smaller than the space for recursion inside ARexx.

Last edited by idrougge; 13 November 2016 at 04:28.
idrougge is offline  
Old 13 November 2016, 04:28   #38
idrougge
Registered User
 
Join Date: Sep 2007
Location: Stockholm
Posts: 4,332
This one:
Code:
   DO FOREVER
      if (Left(dstring,1) == ' ') then
         dstring = DelStr(dstring,1,1)
      else Leave
   END
can be shortened to:
Code:
dstring=Strip(dstring)
This:
Code:
if (Compare(Upper(SubStr(cfile,(clength-4))),".INFO") ~= 0)
can be shortened to:
Code:
if Right(Upper(cfile),5) ~= '.info'
What is the point in opening and reading each cfile? Seeing if they're executables?
idrougge is offline  
Old 13 November 2016, 06:58   #39
Pheonix
Registered User
 
Join Date: Aug 2009
Location: Waco USA
Posts: 253
Well, I've dropped the process nesting path already. So the checks to either load or unload rexxsupport.library are only being made once now. Also, when I "did" have the process nest path going, it only loaded it the first time, and unloaded it after everything was done and it was completely finished. The only parts that hit every time was the "Is it loaded?" line and the "Did I load it?" line. On the second call, it was already loaded, so LLoad would be set to 0 (I didn't load it,) and when that call ended, it would just leave it in the list. The assumption being, some other script had loaded it, and still needs it.

As for cleanup, usually the code doesn't make enough of a difference to make breaking the habit worthwhile. It usually only amounts to 1 or 2 lines of code. On the bigger projects, it is usually a small function with a table of handles: Is this file still open? Close it. etc... I've actually learned, the hard way, that you can't completely trust an operating environment to always handle that for you. I'm self taught, and originally I wasn't so stringent about it (even though the books I was using at the time stated it as a good habit.) You can never be 100% sure when something else, running in the background, can interfere with normal operations.

In this particular case, there are actually only 3 lines that are involved with what could be considered unnecessary cleanup. Setting Lload to 0 if the library is already loaded. Setting it to 1 if I have loaded the library. And closing it if I have. They each take place only once now.

As for why I'm reading the .info file every time, it's to weed out the drawer icons. WBLoad will error out if you point it to the icon file for a drawer (type 2, located at position 48 in the icon file.) So, I open the file, seek to position 48 (a lot better than the original read 48 bytes and check the last one,) then read the byte and see if it's a drawer or not. If it is, skip it and move on to the next one.

Thanks for the Strip() function I hadn't gotten there yet. I had already simplified the ".info" check a bit, but am currently kicking myself for not thinking about Right(). I used Left() quite extensively, why couldn't I think about Right()?

I was originally using Compare() with everything because I kept getting "That's not a Boolean" messages without it. I've since found out that that was actually being caused by something else I had been doing wrong, and had already fixed. I had removed the Compare() usage for most of the cases, but I had missed that one Thanks for pointing it out.

Right now, the script's function is to scan a drawer for Icon files and process all non-drawer icons through a program of my selection. If there are sub-folders, then it will either ignore them or process them as well (depending on the -s setting.) That's all it does, and all I want it to do. I can feed the icon files to WBLoad, or to WBRun (assuming I figure out why it doesn't want to work for me,) or to something else entirely. About the only thing left would be to put in the option of leaving the .info on what is passed to the final program or not. Also, if there is a way, set it up to "wait" each time for whatever is used to close before moving on to the next icon. Then it could be used for more than just the original purpose. Set it up to load all the icons in a directory into your favorite editor, you do what you are trying to do, then save/exit, and up pops the next icon for you (as one possible example.) Though, in that case, would want to add in options to change which icons will be ignored, if any.
Attached Files
File Type: txt WBStart.txt (2.5 KB, 100 views)
Pheonix is offline  
Old 13 November 2016, 16:46   #40
idrougge
Registered User
 
Join Date: Sep 2007
Location: Stockholm
Posts: 4,332
Without actually profiling your script, I think there's a potentially big overhead in reading each .info file. Since you already can filter out drawers from files, you could just scan your list to see if there's a matching file for each .info entry.

For example:
Code:
IF Right(cfile,5) == '.info' THEN DO
  SAY 'Found an icon:' cfile
  PARSE VAR cfile cfile '.info' .
  IF Pos(cfile, flist) ~= 0 THEN DO
    SAY 'Found matching (non-directory) file'
    /* Run program here */
    END
  END

Last edited by idrougge; 13 November 2016 at 16:59.
idrougge is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
How to make an Workbench Icon running a CLI Script ? Marskilla support.Other 9 26 April 2016 23:11
External windows program communicating with program running inside WinUAE xxxxx support.WinUAE 10 19 February 2013 09:27
Possible to run a program from CLI in background? VoltureX support.Apps 17 14 January 2012 03:16
CLI program to resturn joy direction or fire button. olesio request.Apps 26 04 November 2011 18:18
CLI program to make mouse pointer dissapear on KS 3.X Gaula92 request.Apps 5 21 October 2011 14:49

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 17:05.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.23066 seconds with 14 queries