opendir sequence
Brian K. White
brian at aljex.com
Mon Nov 9 15:23:05 PST 2015
On 9/27/2012 2:01 AM, Fairlight wrote:
> On Wed, Sep 26, 2012 at 10:31:58AM -0500, Scott Nelson thus spoke:
>> fP 5.06 on SCO OSE 6
>>
>> It appears that opendir reads the requested directory the same as doing
>> an 'l' to list, by name order. Is there a way to read the listing with
>> opendir in date / time order?
>
> Nope, not inherently. You're at the mercy of what readdir gives you in
> terms of order.
>
> Your only recourse is limited. Store all file information in arrays and
> then re-sort the array. Cakewalk in perl, horrendously painful in fP--and
> limited by the maximum size of your array.
>
> mark->
>
I was just about to ask if anyone had a good array sort routine for this
very same purpose. That's why I searched my saved emails first and found
this.
I just wrote a file-select call table in pure fp, and I did include a
bubble-sort gosub, but it's pretty slow. Bubble sort is very small and
easy to translate from generic BASIC or pseudo-code examples into fp
processing. The only fancy function it needs is if you're sorting text
strings, then some way to compare text strings, which is one thing we do
have very easy in fp. We can throw and numerical or alpha strings
together and compare them and get a sensible result as if it were all
simple integers.
But it's a bit slow for generating a directory listing as frequently as
this will be used. Tolerable, but noticeable. A full second or more to
display our main filepro directory.
So I was about to investigate implementing some other sorting algorithm
besides bubble sort, but they are all more complicated and require
functions like bitwise ops that we don't have, and might not be
practical to implement in processing. I mean if a more efficient
algorithm required a bitwise-xor, you COULD write a gosub that turned
integers into strings of 1&0 and then walk through those strings one
char at a time... but I'm sure the result would be even slower than the
original plain bubble sort!
Conversely if no one implemented any kind of array sort, here is the
simple bubble sort at least if you want.
Not possible to dim an array of variable size, so you have to pick a max
number of elements and hardcode it up front. So this uses 2048. A
directory can certainly have more than 2048 entries in it so this will
fail on any of those. You could declare the arrays larger than 2048
array if you want.
The harm from dimming a lot of array elements is mostly limited to using
up memory. The loops and the listbox all just work from 1-to-N, where N
is the return value from opendir(), and ignore the rest. So you could
probably go ahead and dim a little more.
For reference:
2k (2048) elements per array * 32 bytes per element * 2 arrays =
131072 bytes (128KB) per running instance of this call table.
32k (32768) elements would be 2MB per instance.
That's on top of whatever fp is maintaining internally to provide
@DIRLIST*[] in the first place.
So at 32k elements, if 100 users each had 3 windows open with this in
each of them all at the same time, that would be 600M used by this
routine. Hm. Maybe it's fine to just go ahead and dim them up around 32k
after all. Unless it takes extra seconds for FP to allocate all that
each time the routine is called.
filenames (just the filename part, not counting the leading path) can be
longer than 32 characters, but @DIRLIST_FILENAME[] only returns 32 bytes
per entry, so there's no point in dimming the array elements any larger.
If: 'directory list ; temp copy for bubble sort
Then: dim dirl[2048](32) ; dim tmpl[2048](32)
If:
Then: d = getenv("PFDATA"){getenv("PFDIR"){"/filepro"
If:
Then: n = opendir("*",d) ; i = "1"
cpd If: i le n
Then: dirl[i] = @DIRLIST_FILENAME[i] ; i = i + "1" ; goto cpd
If:
Then: x = closedir()
If:
Then: gosub bsrt
[...]
bsrt If: '*** bubble sort dirl[] ***
Then: ' works but slow
If:
Then: i = "1"
bsi If:
Then: r = "1"
bsr If: dirl[r] gt dirl[r+"1"]
Then: tmpl[r]=dirl[r] ;dirl[r]=dirl[r+"1"] ;dirl[r+"1"]=tmpl[r]
If: r lt n-i
Then: r = r + "1" ; goto bsr
If: i lt n
Then: i = i + "1" ; goto bsi
If:
Then: return ' bsrt
I was going to ask if anyone had a better sort routine to share already
implemented, but given that 32 character limit, and the speed, and
another little problem having to hard code some logic and values from
sys/stat.h instead of being able to use IS_DIR(m) like you're supposed
to, it's probably actually better to just give up on the "pure filepro"
goal and make a user() co-process that uses normal system utils to get
file listings, sorted, with metadata.
But I came pretty close.
I have it displaying directory contents, current path to currently
displayed directory, you can navigate up and down through directories,
meaning it shows . and .. in the listbox, and if you select "..", it
strips off a path element and displays the listing for the parent dir.
When you select an item, it looks at @FSTAT["3"] and determines if it's
a directory, and if it's a directory it adds it to the path and displays
that new directory. If it's not a dir then it considers that file your
final selection and returns. If you select "." then it considers the
directory you are in as your selection instead of one of it's files or
navigating to a parent or child dir.
If you comment out the gosub bsrt it's pretty fast, and most filenames
happen to be under 32 bytes long so it handles most cases. It just can't
get any better than those "mosts".
--
bkw
More information about the Filepro-list
mailing list