QB64.org Forum

Active Forums => QB64 Discussion => Topic started by: Dav on January 23, 2021, 01:41:52 pm

Title: Question about using SHELL "dir" on non windows OS.
Post by: Dav on January 23, 2021, 01:41:52 pm
I'm working on a simple file selection box SUB which uses SHELL "dir" calls to get filenames and directory info.  Wanting to make to code compatible with linux and macs, I was wondering what changes if any in the SHELL call I would need to make it work on those OS.  Or would a SHELL "dir" call not work at all on them?  I only can test on Windows right now, not sure about SHELLIng on linux or Mac.  Thanks....

- Dav
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: odin on January 23, 2021, 01:46:33 pm
Here's how it's done by the IDE, works on all platforms:

Code: QB64: [Select]
  1. FUNCTION idezfilelist$ (path$, method, mask$) 'method0=*.bas, method1=*.*, method2=custom mask
  2.     DIM sep AS STRING * 1
  3.     sep = CHR$(0)
  4.  
  5.     IF os$ = "WIN" THEN
  6.         OPEN ".\internal\temp\files.txt" FOR OUTPUT AS #150: CLOSE #150
  7.         IF method = 0 THEN SHELL _HIDE "dir /b /ON /A-D " + QuotedFilename$(path$) + "\*.bas >.\internal\temp\files.txt"
  8.         IF method = 1 THEN SHELL _HIDE "dir /b /ON /A-D " + QuotedFilename$(path$) + "\*.* >.\internal\temp\files.txt"
  9.         IF method = 2 THEN SHELL _HIDE "dir /b /ON /A-D " + QuotedFilename$(path$) + "\" + QuotedFilename$(mask$) + " >.\internal\temp\files.txt"
  10.         filelist$ = ""
  11.         OPEN ".\internal\temp\files.txt" FOR INPUT AS #150
  12.         DO UNTIL EOF(150)
  13.             LINE INPUT #150, a$
  14.             IF LEN(a$) THEN 'skip blank entries
  15.                 IF filelist$ = "" THEN filelist$ = a$ ELSE filelist$ = filelist$ + sep + a$
  16.             END IF
  17.         LOOP
  18.         CLOSE #150
  19.         idezfilelist$ = filelist$
  20.         EXIT FUNCTION
  21.     END IF
  22.  
  23.     IF os$ = "LNX" THEN
  24.         filelist$ = ""
  25.         IF method = 0 THEN
  26.             FOR i = 1 TO 2
  27.                 OPEN "./internal/temp/files.txt" FOR OUTPUT AS #150: CLOSE #150
  28.                 IF i = 1 THEN SHELL _HIDE "find " + QuotedFilename$(path$) + " -maxdepth 1 -type f -name " + CHR$(34) + "*.bas" + CHR$(34) + " | sort >./internal/temp/files.txt"
  29.                 IF i = 2 THEN SHELL _HIDE "find " + QuotedFilename$(path$) + " -maxdepth 1 -type f -name " + CHR$(34) + "*.BAS" + CHR$(34) + " | sort >./internal/temp/files.txt"
  30.                 GOSUB AddToList
  31.             NEXT
  32.         ELSEIF method = 1 THEN
  33.             SHELL _HIDE "find " + QuotedFilename$(path$) + " -maxdepth 1 -type f -name " + CHR$(34) + "*" + CHR$(34) + " | sort >./internal/temp/files.txt"
  34.             GOSUB AddToList
  35.         ELSEIF method = 2 THEN
  36.             SHELL _HIDE "find " + QuotedFilename$(path$) + " -maxdepth 1 -type f -name " + CHR$(34) + mask$ + CHR$(34) + " | sort >./internal/temp/files.txt"
  37.             GOSUB AddToList
  38.         END IF
  39.         idezfilelist$ = filelist$
  40.         EXIT FUNCTION
  41.  
  42.         AddToList:
  43.         OPEN "./internal/temp/files.txt" FOR INPUT AS #150
  44.         DO UNTIL EOF(150)
  45.             LINE INPUT #150, a$
  46.             IF LEN(a$) = 0 THEN EXIT DO
  47.             FOR x = LEN(a$) TO 1 STEP -1
  48.                 a2$ = MID$(a$, x, 1)
  49.                 IF a2$ = "/" THEN
  50.                     a$ = RIGHT$(a$, LEN(a$) - x)
  51.                     EXIT FOR
  52.                 END IF
  53.             NEXT
  54.             IF filelist$ = "" THEN filelist$ = a$ ELSE filelist$ = filelist$ + sep + a$
  55.         LOOP
  56.         CLOSE #150
  57.         RETURN
  58.     END IF
  59.  
  60.  
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: Dav on January 23, 2021, 01:50:42 pm
Thanks, odin!

- Dav
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: Pete on January 23, 2021, 02:00:16 pm
That's a time saver, Dav. I could have told you Linux uses the exact same dir command, but that the switches and output format are different than Windows. It's neat to see the QB64 conversions needed to convert that information, which I take means that a SHELL in QB64 will produce the same output format, I would hope, when doing something like SHELL _HIDE "dir *.*>tmp.tmp

So provided the Windows tmp,tmp file appeared in the same format for file names, dates, and file size, and had the same headers, etc. you could rely on one open and read method to extract and parse the info correctly for both platforms. In other words, more is needed than the Windows /b (bare) switch for date and file size info.

As for Mac, it is stated to be POSIX compliant, so I would hope it can be handled the same as Windows for directory output.

Maybe you could make a simple snippet for Fell, who I believe has a Mac and Linux system, and ask him to post the output. If your Windows results match his Linux and Apple results, your golden. That may not even be necessary, but I'd take fact over theory, everyday. (Sorry Bill!).

Pete
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: bplus on January 23, 2021, 02:32:29 pm
There is another cross platform approach that will give you a Directory's List array and a File's list array for a given folder or directory, it happens to be current Best Answer in this thread:
https://www.qb64.org/forum/index.php?topic=1511.msg122368#msg122368

Looks like you will have to parse out the files' string returned by odin's function.

 
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: SMcNeill on January 23, 2021, 02:59:22 pm
There is another cross platform approach that will give you a Directory's List array and a File's list array for a given folder or directory, it happens to be current Best Answer in this thread:
https://www.qb64.org/forum/index.php?topic=1511.msg122368#msg122368

Looks like you will have to parse out the files' string returned by odin's function.

You might want to attach direntry.h to that post, so folks can find it and download it.
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: bplus on January 23, 2021, 03:46:09 pm
You might want to attach direntry.h to that post, so folks can find it and download it.

OK
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: Dav on January 23, 2021, 04:23:01 pm
Thanks for the link, @bplus.  I think I glanced at that once before, but had my interest elsewhere at the time and forgot about it.  Very glad to see it again.  Looks like it's what I'm after.

Here's what I had started working on, was going to add directory info and navigating, and allow a graphics version too.

- Dav

Code: QB64: [Select]
  1.  
  2. a$ = FileSelect$(5, 10, 15, 55, "*.*")
  3.  
  4. IF a$ <> "" THEN
  5.     PRINT "You selected: "; a$
  6.  
  7.  
  8.  
  9. FUNCTION FileSelect$ (y, x, y2, x2, Filespec$)
  10.  
  11.     '=== save original place of cursor
  12.     origy = CSRLIN: origx = POS(1)
  13.  
  14.     '=== Save whole screen
  15.     DIM scr1 AS _MEM, scr2 AS _MEM
  16.     scr1 = _MEMIMAGE(0): scr2 = _MEMNEW(scr1.SIZE)
  17.     _MEMCOPY scr1, scr1.OFFSET, scr1.SIZE TO scr2, scr2.OFFSET
  18.  
  19.     SHELL _HIDE "DIR " + Filespec$ + " /b > $_TeMP_FILE_LIST"
  20.  
  21.     'get list...
  22.     REDIM FileNames$(5000) 'space for 5000 filenames
  23.  
  24.     FF = FREEFILE
  25.     OPEN "$_TeMP_FILE_LIST" FOR INPUT AS #FF
  26.     LineCount = 0
  27.     WHILE ((LineCount < UBOUND(FileNames$)) AND (NOT EOF(FF)))
  28.         LINE INPUT #FF, rl$
  29.         'skip the temp file...
  30.         IF rl$ <> "$_TeMP_FILE_LIST" THEN
  31.             FileNames$(LineCount) = rl$
  32.             LineCount = LineCount + 1
  33.         END IF
  34.     WEND
  35.     CLOSE #FF
  36.  
  37.     KILL "$_TeMP_FILE_LIST"
  38.  
  39.     'draw a box
  40.     COLOR _RGB(100, 100, 255)
  41.     FOR l = 0 TO y2 + 1
  42.         LOCATE y + l, x: PRINT STRING$(x2 + 4, CHR$(219));
  43.     NEXT
  44.  
  45.     DO
  46.  
  47.         FOR l = 0 TO (y2 - 1)
  48.             LOCATE (y + 1) + l, (x + 2)
  49.             IF l + top = Selection THEN
  50.                 COLOR _RGB(0, 0, 0), _RGB(255, 255, 255) 'selected line
  51.             ELSE
  52.                 COLOR _RGB(255, 255, 255), _RGB(0, 0, 0) 'regular
  53.             END IF
  54.             PRINT LEFT$(FileNames$(top + l) + STRING$(x2, " "), x2);
  55.         NEXT
  56.  
  57.         k$ = INKEY$
  58.         SELECT CASE k$
  59.             CASE IS = CHR$(0) + CHR$(72) 'Up arrow
  60.                 IF Selection > 0 THEN Selection = Selection - 1
  61.                 IF Selection < top THEN top = Selection
  62.             CASE IS = CHR$(0) + CHR$(80) 'Down Arrow
  63.                 IF Selection < (LineCount - 1) THEN Selection = Selection + 1
  64.                 IF Selection > (top + (y2 - 2)) THEN top = Selection - y2 + 1
  65.             CASE IS = CHR$(0) + CHR$(73) 'Page up
  66.                 top = top - y2
  67.                 Selection = Selection - y2
  68.                 IF top < 0 THEN top = 0
  69.                 IF Selection < 0 THEN Selection = 0
  70.             CASE IS = CHR$(0) + CHR$(81) 'Page Down
  71.                 top = top + y2
  72.                 Selection = Selection + y2
  73.                 IF top >= LineCount - y2 THEN top = LineCount - y2
  74.                 IF top < 0 THEN top = 0
  75.                 IF Selection >= LineCount THEN Selection = LineCount - 1
  76.             CASE IS = CHR$(0) + CHR$(71) 'Home
  77.                 top = 0: Selection = 0
  78.             CASE IS = CHR$(0) + CHR$(79) 'End
  79.                 Selection = LineCount - 1
  80.                 top = Selection - y2 + 1
  81.                 IF top < 0 THEN top = 0
  82.             CASE IS = CHR$(27) ' ESC cancels
  83.                 FileSelect$ = ""
  84.                 EXIT DO
  85.             CASE IS = CHR$(13) 'Enter
  86.                 FileSelect$ = RTRIM$(FileNames$(Selection))
  87.                 EXIT DO
  88.         END SELECT
  89.     LOOP
  90.  
  91.     _KEYCLEAR
  92.  
  93.     '=== Restore the whole screen
  94.     _MEMCOPY scr2, scr2.OFFSET, scr2.SIZE TO scr1, scr1.OFFSET
  95.     _MEMFREE scr1: _MEMFREE scr2
  96.  
  97.     '=== restore original y,x
  98.     LOCATE origy, origx
  99.  
  100.  
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: bplus on January 23, 2021, 04:32:45 pm
Yeah, I like the fileSpec$ aspect of both odin's and Dav's.
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: Pete on January 23, 2021, 04:48:07 pm
Been there, done that, but at some point I'm going to have to add a directory tree to my routine, too. I like to use BINARY instead of INPUT in all my files operations. If you  want to include date an time, let me know; otherwise /b is a nice command line switch to get just the file names. I use it a lot but for files, I like to see when they were created.

Pete
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: Dav on January 23, 2021, 06:24:48 pm
Yeah, I want to show the file info too eventually.  I have API routines to do all that, but was aiming for a cross compatible way.  And seeing how you use SHELL _HIDE often to your advantage kind of motivated me with it.

I planned to get Directories first  (SHELL dir /d), then another call for files, combine both to the Filenames$ array.  Selecting directory name will change to that directory.  Maybe put a ".." selection at the top of the list to go up one directory.  Was thinking that combining SHELL with QB64's builtin directory commands could handle all that, and work on all platforms.

- Dav
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: Pete on January 23, 2021, 06:43:58 pm
I'm thinking along the same lines. something like this...

..
[Directory-1]
[Directory-2]
[Directory-3]
Filename1.txt
Filename2.text
Filename3.txt

etc.

Fairly easy to do by making a DIR only call, followed a files only call. add the .., directories, and the files. I track the entry numbers, so all I'll need to know is the entry number that changes from a directory to a file.

In windows there re several options to organize the output. Date of creation, alphabetically, etc. It's a time saver, but in days past I made functions to convert to army time, and sort dates, names, etc. For a list of all switches, visit the easy.dos.com site.

Fun stuff,

Pete
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: Dav on January 23, 2021, 06:52:20 pm
Yes, it's fun to me trying to find workarounds.   I was thinking of just adding the [ ] to the dir names when saving them in the array, and then just strip the [ ] out before using the names to change directories. 

- Dav
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: Pete on January 23, 2021, 07:05:03 pm
What I would like, beyond what we are discussing, is a root navigation option. I'm not sure if I'll do that as a second popup, like a right click, or make some sort of flip screen. It's just a whole lot faster to move around to the folders you want to access that way. Of course another option is a dir input line, where you can click somewhere within that line, and it shortens to where you clicked and then displays that directory to the screen like:

c:\QB64\myprograms\

So click anywhere on qb64, and it shortens the url to: c:\qb64, and then opens that directory.

That lateral scrolling routine would make that method quite possible, still, it isn't as fast as with all the opens that Explorer has to offer.

Pete
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: Dav on January 25, 2021, 04:15:09 pm
Here's what I got so far, thanks @Pete for dir command help.  Seems to work ok for me this way. 

Right now it's just for Windows still.  I might make directories a slightly different color.

You can navigate directories, just press enter to enter them.  Enter on filename to select it.

- Dav

Code: QB64: [Select]
  1.  
  2. a$ = FileSelect$(5, 10, 15, 55, "*.*")
  3.  
  4. IF a$ <> "" THEN
  5.     PRINT "You selected: "; a$
  6.  
  7.  
  8.  
  9. FUNCTION FileSelect$ (y, x, y2, x2, Filespec$)
  10.  
  11.     '=== save original place of cursor
  12.     origy = CSRLIN: origx = POS(1)
  13.  
  14.     '=== Save whole screen
  15.     DIM scr1 AS _MEM, scr2 AS _MEM
  16.     scr1 = _MEMIMAGE(0): scr2 = _MEMNEW(scr1.SIZE)
  17.     _MEMCOPY scr1, scr1.OFFSET, scr1.SIZE TO scr2, scr2.OFFSET
  18.  
  19.     loadagain:
  20.     top = 0
  21.     selection = 0
  22.  
  23.     SHELL _HIDE "DIR /b /A:D > $_TeMP_FILE_LIST"
  24.  
  25.     'get list...
  26.     REDIM FileNames$(5000) 'space for 5000 filenames
  27.  
  28.     FileNames$(0) = ".."
  29.  
  30.     FF = FREEFILE
  31.     OPEN "$_TeMP_FILE_LIST" FOR INPUT AS #FF
  32.  
  33.     LineCount = 1
  34.     WHILE ((LineCount < UBOUND(FileNames$)) AND (NOT EOF(FF)))
  35.         LINE INPUT #FF, rl$
  36.         FileNames$(LineCount) = "[" + rl$ + "]"
  37.         LineCount = LineCount + 1
  38.     WEND
  39.     CLOSE #FF
  40.  
  41.     KILL "$_TeMP_FILE_LIST"
  42.  
  43.     SHELL _HIDE "DIR /b /A:-D " + Filespec$ + " > $_TeMP_FILE_LIST"
  44.  
  45.     FF = FREEFILE
  46.     OPEN "$_TeMP_FILE_LIST" FOR INPUT AS #FF
  47.     WHILE ((LineCount < UBOUND(FileNames$)) AND (NOT EOF(FF)))
  48.         LINE INPUT #FF, rl$
  49.         'skip the temp file...
  50.         IF rl$ <> "$_TeMP_FILE_LIST" THEN
  51.             FileNames$(LineCount) = rl$
  52.             LineCount = LineCount + 1
  53.         END IF
  54.     WEND
  55.     CLOSE #FF
  56.  
  57.     KILL "$_TeMP_FILE_LIST"
  58.  
  59.     'draw a box
  60.     COLOR _RGB(100, 100, 255)
  61.     FOR l = 0 TO y2 + 1
  62.         LOCATE y + l, x: PRINT STRING$(x2 + 4, CHR$(219));
  63.     NEXT
  64.  
  65.     DO
  66.  
  67.         FOR l = 0 TO (y2 - 1)
  68.             LOCATE (y + 1) + l, (x + 2)
  69.             IF l + top = selection THEN
  70.                 COLOR _RGB(0, 0, 0), _RGB(255, 255, 255) 'selected line
  71.             ELSE
  72.                 COLOR _RGB(255, 255, 255), _RGB(0, 0, 0) 'regular
  73.             END IF
  74.             PRINT LEFT$(FileNames$(top + l) + STRING$(x2, " "), x2);
  75.         NEXT
  76.  
  77.         k$ = INKEY$
  78.         SELECT CASE k$
  79.             CASE IS = CHR$(0) + CHR$(72) 'Up arrow
  80.                 IF selection > 0 THEN selection = selection - 1
  81.                 IF selection < top THEN top = selection
  82.             CASE IS = CHR$(0) + CHR$(80) 'Down Arrow
  83.                 IF selection < (LineCount - 1) THEN selection = selection + 1
  84.                 IF selection > (top + (y2 - 2)) THEN top = selection - y2 + 1
  85.             CASE IS = CHR$(0) + CHR$(73) 'Page up
  86.                 top = top - y2
  87.                 selection = selection - y2
  88.                 IF top < 0 THEN top = 0
  89.                 IF selection < 0 THEN selection = 0
  90.             CASE IS = CHR$(0) + CHR$(81) 'Page Down
  91.                 top = top + y2
  92.                 selection = selection + y2
  93.                 IF top >= LineCount - y2 THEN top = LineCount - y2
  94.                 IF top < 0 THEN top = 0
  95.                 IF selection >= LineCount THEN selection = LineCount - 1
  96.             CASE IS = CHR$(0) + CHR$(71) 'Home
  97.                 top = 0: selection = 0
  98.             CASE IS = CHR$(0) + CHR$(79) 'End
  99.                 selection = LineCount - 1
  100.                 top = selection - y2 + 1
  101.                 IF top < 0 THEN top = 0
  102.             CASE IS = CHR$(27) ' ESC cancels
  103.                 FileSelect$ = ""
  104.                 EXIT DO
  105.             CASE IS = CHR$(13) 'Enter
  106.                 'go up one dir
  107.                 IF RTRIM$(FileNames$(selection)) = ".." THEN
  108.                     cd$ = _CWD$
  109.                     cd$ = LEFT$(cd$, _INSTRREV(cd$, "\"))
  110.                     CHDIR cd$
  111.                     ERASE FileNames$
  112.                     GOTO loadagain
  113.                 END IF
  114.                 'see if directory
  115.                 test$ = RTRIM$(FileNames$(selection))
  116.                 IF LEFT$(test$, 1) = "[" THEN
  117.                     test$ = MID$(test$, 2, LEN(test$) - 2)
  118.                     CHDIR test$
  119.                     ERASE FileNames$
  120.                     GOTO loadagain
  121.                 ELSE
  122.                     IF RIGHT$(_CWD$, 1) = "\" THEN
  123.                         c$ = _CWD$
  124.                     ELSE
  125.                         c$ = _CWD$ + "\"
  126.                     END IF
  127.                     FileSelect$ = c$ + RTRIM$(FileNames$(selection))
  128.                     EXIT DO
  129.                 END IF
  130.         END SELECT
  131.     LOOP
  132.  
  133.     _KEYCLEAR
  134.  
  135.     '=== Restore the whole screen
  136.     _MEMCOPY scr2, scr2.OFFSET, scr2.SIZE TO scr1, scr1.OFFSET
  137.     _MEMFREE scr1: _MEMFREE scr2
  138.  
  139.     '=== restore original y,x
  140.     LOCATE origy, origx
  141.  
  142.  
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: Dav on January 25, 2021, 09:41:17 pm
Although Steve has provided me a better file select solution, I wanted to go ahead and finish up the SHELL version, so I added the Linux find command if linux OS is detected.   If one of you kind linux people could test this and see if this works for you I'd appreciate it.  Thanks.  I used to have QB64 on linux mint pen drive, but lost it...

Also, this function changes the foreground and background COLOR attributes.  I'd like to restore those upon exiting.  Is there a way to do that?  I'm trying _DEFAULTCOLOR, but it seems to only save foreground (text).  The background color stays changed. (fixed...)

- Dav

Code: QB64: [Select]
  1.  
  2. a$ = FileSelect$(5, 10, 15, 55, "*.*")
  3.  
  4. IF a$ <> "" THEN
  5.     PRINT "You selected: "; a$
  6.  
  7.  
  8.  
  9. FUNCTION FileSelect$ (y, x, y2, x2, Filespec$)
  10.  
  11.     '=== save original place of cursor
  12.     origy = CSRLIN: origx = POS(1)
  13.  
  14.     '=== save colors
  15.     fg& = _DEFAULTCOLOR
  16.     bg& = _BACKGROUNDCOLOR
  17.  
  18.     '=== Save whole screen
  19.     DIM scr1 AS _MEM, scr2 AS _MEM
  20.     scr1 = _MEMIMAGE(0): scr2 = _MEMNEW(scr1.SIZE)
  21.     _MEMCOPY scr1, scr1.OFFSET, scr1.SIZE TO scr2, scr2.OFFSET
  22.  
  23.     loadagain:
  24.  
  25.     top = 0
  26.     selection = 0
  27.  
  28.     IF INSTR(_OS$, "LINUX") THEN
  29.         SHELL _HIDE "find . -type d > $_TeMP_FILE_LIST"
  30.     ELSE
  31.         SHELL _HIDE "dir /b /A:D > $_TeMP_FILE_LIST"
  32.     END IF
  33.  
  34.     'get list...
  35.     REDIM FileNames$(5000) 'space for 5000 filenames
  36.  
  37.     FileNames$(0) = ".."
  38.  
  39.     FF = FREEFILE
  40.     OPEN "$_TeMP_FILE_LIST" FOR INPUT AS #FF
  41.  
  42.     LineCount = 1
  43.     WHILE ((LineCount < UBOUND(FileNames$)) AND (NOT EOF(FF)))
  44.         LINE INPUT #FF, rl$
  45.         FileNames$(LineCount) = "[" + rl$ + "]"
  46.         LineCount = LineCount + 1
  47.     WEND
  48.     CLOSE #FF
  49.  
  50.     KILL "$_TeMP_FILE_LIST"
  51.  
  52.     IF INSTR(_OS$, "LINUX") THEN
  53.         SHELL _HIDE "find . -type f " + CHR$(34) + Filespec$ + CHR$(34) + " > $_TeMP_FILE_LIST"
  54.     ELSE
  55.         SHELL _HIDE "dir /b /A:-D " + Filespec$ + " > $_TeMP_FILE_LIST"
  56.     END IF
  57.  
  58.     FF = FREEFILE
  59.     OPEN "$_TeMP_FILE_LIST" FOR INPUT AS #FF
  60.     WHILE ((LineCount < UBOUND(FileNames$)) AND (NOT EOF(FF)))
  61.         LINE INPUT #FF, rl$
  62.         'skip the temp file...
  63.         IF rl$ <> "$_TeMP_FILE_LIST" THEN
  64.             FileNames$(LineCount) = rl$
  65.             LineCount = LineCount + 1
  66.         END IF
  67.     WEND
  68.     CLOSE #FF
  69.  
  70.     KILL "$_TeMP_FILE_LIST"
  71.  
  72.     'draw a box
  73.     COLOR _RGB(100, 100, 255)
  74.     FOR l = 0 TO y2 + 1
  75.         LOCATE y + l, x: PRINT STRING$(x2 + 4, CHR$(219));
  76.     NEXT
  77.  
  78.     DO
  79.  
  80.         FOR l = 0 TO (y2 - 1)
  81.             LOCATE (y + 1) + l, (x + 2)
  82.             IF l + top = selection THEN
  83.                 COLOR _RGB(0, 0, 0), _RGB(255, 255, 255) 'selected line
  84.             ELSE
  85.                 COLOR _RGB(255, 255, 255), _RGB(0, 0, 0) 'regular
  86.             END IF
  87.             PRINT LEFT$(FileNames$(top + l) + STRING$(x2, " "), x2);
  88.         NEXT
  89.  
  90.         k$ = INKEY$
  91.         SELECT CASE k$
  92.             CASE IS = CHR$(0) + CHR$(72) 'Up arrow
  93.                 IF selection > 0 THEN selection = selection - 1
  94.                 IF selection < top THEN top = selection
  95.             CASE IS = CHR$(0) + CHR$(80) 'Down Arrow
  96.                 IF selection < (LineCount - 1) THEN selection = selection + 1
  97.                 IF selection > (top + (y2 - 2)) THEN top = selection - y2 + 1
  98.             CASE IS = CHR$(0) + CHR$(73) 'Page up
  99.                 top = top - y2
  100.                 selection = selection - y2
  101.                 IF top < 0 THEN top = 0
  102.                 IF selection < 0 THEN selection = 0
  103.             CASE IS = CHR$(0) + CHR$(81) 'Page Down
  104.                 top = top + y2
  105.                 selection = selection + y2
  106.                 IF top >= LineCount - y2 THEN top = LineCount - y2
  107.                 IF top < 0 THEN top = 0
  108.                 IF selection >= LineCount THEN selection = LineCount - 1
  109.             CASE IS = CHR$(0) + CHR$(71) 'Home
  110.                 top = 0: selection = 0
  111.             CASE IS = CHR$(0) + CHR$(79) 'End
  112.                 selection = LineCount - 1
  113.                 top = selection - y2 + 1
  114.                 IF top < 0 THEN top = 0
  115.             CASE IS = CHR$(27) ' ESC cancels
  116.                 FileSelect$ = ""
  117.                 EXIT DO
  118.             CASE IS = CHR$(13) 'Enter
  119.                 'go up one dir
  120.                 IF RTRIM$(FileNames$(selection)) = ".." THEN
  121.                     cd$ = _CWD$
  122.                     cd$ = LEFT$(cd$, _INSTRREV(cd$, "\"))
  123.                     CHDIR cd$
  124.                     ERASE FileNames$
  125.                     GOTO loadagain
  126.                 END IF
  127.                 'see if directory
  128.                 test$ = RTRIM$(FileNames$(selection))
  129.                 IF LEFT$(test$, 1) = "[" THEN
  130.                     test$ = MID$(test$, 2, LEN(test$) - 2)
  131.                     CHDIR test$
  132.                     ERASE FileNames$
  133.                     GOTO loadagain
  134.                 ELSE
  135.                     IF RIGHT$(_CWD$, 1) = "\" THEN
  136.                         c$ = _CWD$
  137.                     ELSE
  138.                         c$ = _CWD$ + "\"
  139.                     END IF
  140.                     FileSelect$ = c$ + RTRIM$(FileNames$(selection))
  141.                     EXIT DO
  142.                 END IF
  143.         END SELECT
  144.     LOOP
  145.  
  146.     _KEYCLEAR
  147.  
  148.     '=== Restore the whole screen
  149.     _MEMCOPY scr2, scr2.OFFSET, scr2.SIZE TO scr1, scr1.OFFSET
  150.     _MEMFREE scr1: _MEMFREE scr2
  151.  
  152.     '=== restore original y,x
  153.     LOCATE origy, origx
  154.  
  155.     COLOR fg&, bg&
  156.  
  157.  
  158.  
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: FellippeHeitor on January 25, 2021, 09:43:21 pm
There's _DEFAULTCOLOR for the foreground and _BACKGROUNDCOLOR for the bg. Links to wiki:

Code: QB64: [Select]

Save their values before you change COLOR, then restore when the procedure ends.
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: Dav on January 25, 2021, 09:45:39 pm
Ah... I missed that one.  Thanks, @FellippeHeitor.

EDIT: I fixed the code.  Restores color as should..

- Dav
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: Pete on January 25, 2021, 09:56:48 pm
Hold on Dav...

Code: QB64: [Select]
  1. COLOR 14, 4
  2. PRINT "SCREEN ZERO HERO!"
  3. ' Now lets save this original color...
  4. LOCATE 1, 1
  5. a = SCREEN(1, 1, 1)
  6. ' Now change color
  7. COLOR 7, 0
  8. LOCATE 3, 1
  9. PRINT "Back to white on black..."
  10. ' Now lets get back to our original color...
  11.  
  12. COLOR a MOD 16, a \ 16
  13. LOCATE 5, 1
  14. PRINT "That's how it's done, old school!"
  15.  

Hey, I just got my dir stuff completed over at QBF, too. I have to smooth a few things out, but it completes the directory searching just fine.

Pete
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: Dav on January 25, 2021, 10:07:31 pm
Hmm,well that seems to work, @Pete.  But I'm not sure how...I must have missed old school class that day!

- Dav
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: Pete on January 25, 2021, 10:21:19 pm
SCREEN has a third parameter that reads the color attribute of the screen. The trick is knowing how to put that value back into the COLOR statement, which is foreground equals the number mod 16 and the background is the number integer division 16.

I'll have to give Steve's stuff a try out tomorrow, and have a peek at yours after you post it.

Pete

Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: FellippeHeitor on January 25, 2021, 10:22:02 pm
Or just keep the _DEFAULTCOLOR and _BACKGROUNDCOLOR approach for all screen modes, 0 included. SCREEN won't work if nothing's been printed though, too.
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: Pete on January 25, 2021, 10:54:13 pm
Fell missed day 2 of Old School...

Code: QB64: [Select]
  1. SCREEN 0, 0, 0, 0
  2. ' PRINT "SCREEN ZERO HERO!"
  3. SCREEN 0, 0, 1, 0
  4. COLOR 14, 4
  5. PRINT " ";
  6. ' Now lets save this original color...
  7. LOCATE 1, 1
  8. a = SCREEN(1, 1, 1)
  9. SCREEN 0, 0, 0, 0
  10. ' Now change color
  11. COLOR 7, 0
  12. LOCATE 3, 1
  13. PRINT "Back to white on black..."
  14. ' Now lets get back to our original color...
  15.  
  16. COLOR a MOD 16, a \ 16
  17. LOCATE 5, 1
  18. PRINT "That's how it's done, old school!"
  19.  

Of course you can just print a blank space to a part of the screen not in use, and read it. Flipping to a separate hidden page is a bit overkill.

Pete
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: FellippeHeitor on January 25, 2021, 11:34:26 pm
@Dav Also, you're saving the last COLOR parameters the user of your library had set - in this case the last COLOR parameters you had set yourself before calling the sub. No way to do that with the SCREEN trick, as you have to pick a location to read the color from.

@Pete ❤️
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: Pete on January 26, 2021, 11:32:15 am
@Dav Also, you're saving the last COLOR parameters the user of your library had set - in this case the last COLOR parameters you had set yourself before calling the sub. No way to do that with the SCREEN trick, as you have to pick a location to read the color from.

@Pete ❤️

There's always a way. If there wasn't, we woudn't have QB64 in the first place. It's just a question of the level of complexity needed in the chewing gum and bailing wire operations. I've gone as far as memory mapping, in a graphics gui thing I put together. This was before _MEMBLOCK came out and made my approach obsolete.

It's always a trade off. Better keywords create easier coding, but take away from solution based thinking on a lower level. One can only hope that coders will be freed up to use those solution skills for higher purposes.

Personally, I wanted this _DEFAULTCOLOR and _BACKGROUNDCOLOR stuff in QuickBASIC. I never could understand why the last color set couldn't be retrieved from memory. In Atari, that was accomplished with PEEK/POKE. Also, speaking of AtariBASIC, we could easily change the 8x8 pixels of any character, into a custom character. That feature made it super easy to underline words. I suppose if I want to do that with QB64, I'd have to go the way of unicode characters. That's probably something I'll be looking into in the near future. Fingers crossed it will include SCREEN 0, the only screen mode anyone should ever need.

Pete
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: Dav on February 05, 2021, 05:38:33 pm
Even though I'll be using direntry.h in the future, I went ahead and finished off this SHELL "dir" file box routine.  By doing so, I found out something worth noting about using KILL.   I was having a problem deleting the temp file using KILL in certain directories, such as "Documents and Settings".  The program would error report the file doesn't exist and halt, even though the file did exist.  Looks like KILL can't be used on files in restricted directories, it won't see them.  So I decided to use SHELL "del" to delete the temp file instead and it won't error out.  The file won't delete that way either under that directory, but the program will continue and not stop.

Here is what I ended up with.  Shows current directory at top now, and the ".." doesn't show when at the root.  Directories are different colors.  I hope I'm doing the right call under linux to delete the temp file.  For Mac, I have no idea...

Edit:  I guess the best thing to do is always use _FILEEXISTS before using KILL, all the time.

- Dav

Code: QB64: [Select]
  1. '==============
  2. 'FILESELECT.BAS
  3. '==============
  4. 'Simple file selector box. Coded by Dav, FEB/2021
  5. '(with the kind help of the QB64.org forum gurus)
  6.  
  7. 'Navigate through directories and select a file.
  8. 'Use arrows, page up/down, home, end to scroll list.
  9. 'Press enter to select highlighted file or enter the dir.
  10.  
  11. 'things to do: auto center box on screen, and ditch x/y input?
  12. '              ...will need to adjust box size based on file/dir chr length
  13. '              Add user defined colors instead...?
  14.  
  15.  
  16. SCREEN _NEWIMAGE(600, 600, 32)
  17.  
  18. CLS , _RGB(32, 32, 32)
  19.  
  20. '=== draw stuff
  21. FOR x = 1 TO 600 STEP 3
  22.     FOR y = 1 TO 600 STEP 3
  23.         PSET (x, y), _RGB(RND * 255, RND * 255, RND * 255)
  24.     NEXT
  25.  
  26. a$ = FileSelect$(5, 10, 15, 55, "*.*")
  27.  
  28. IF a$ <> "" THEN
  29.     PRINT "You selected: "; a$
  30.  
  31.  
  32.  
  33. FUNCTION FileSelect$ (y, x, y2, x2, Filespec$)
  34.  
  35.     '=== save original place of cursor
  36.     origy = CSRLIN: origx = POS(1)
  37.  
  38.     '=== save colors
  39.     fg& = _DEFAULTCOLOR
  40.     bg& = _BACKGROUNDCOLOR
  41.  
  42.     '=== Save whole screen
  43.     DIM scr1 AS _MEM, scr2 AS _MEM
  44.     scr1 = _MEMIMAGE(0): scr2 = _MEMNEW(scr1.SIZE)
  45.     _MEMCOPY scr1, scr1.OFFSET, scr1.SIZE TO scr2, scr2.OFFSET
  46.  
  47.     loadagain:
  48.  
  49.     top = 0
  50.     selection = 0
  51.  
  52.     IF INSTR(_OS$, "LINUX") THEN
  53.         SHELL _HIDE "find . -type d > $_TeMP_FILE_LIST"
  54.     ELSE
  55.         SHELL _HIDE "dir /b /A:D > $_TeMP_FILE_LIST"
  56.     END IF
  57.  
  58.     'get list...
  59.     REDIM FileNames$(5000) 'space for 5000 filenames
  60.  
  61.     'only show the ".." if not at root dir
  62.     IF LEN(_CWD$) <> 3 THEN
  63.         FileNames$(0) = ".."
  64.         LineCount = 1
  65.     ELSE
  66.         LineCount = 0
  67.     END IF
  68.  
  69.     FF = FREEFILE
  70.     OPEN "$_TeMP_FILE_LIST" FOR INPUT AS #FF
  71.  
  72.     WHILE ((LineCount < UBOUND(FileNames$)) AND (NOT EOF(FF)))
  73.         LINE INPUT #FF, rl$
  74.         FileNames$(LineCount) = "[" + rl$ + "]"
  75.         LineCount = LineCount + 1
  76.     WEND
  77.     CLOSE #FF
  78.  
  79.     'KILL "$_TeMP_FILE_LIST"
  80.     IF INSTR(_OS$, "LINUX") THEN
  81.         SHELL _HIDE "rm $_TeMP_FILE_LIST"
  82.         SHELL _HIDE "find . -type f " + CHR$(34) + Filespec$ + CHR$(34) + " > $_TeMP_FILE_LIST"
  83.     ELSE
  84.         SHELL _HIDE "del $_TeMP_FILE_LIST"
  85.         SHELL _HIDE "dir /b /A:-D " + Filespec$ + " > $_TeMP_FILE_LIST"
  86.     END IF
  87.  
  88.     FF = FREEFILE
  89.     OPEN "$_TeMP_FILE_LIST" FOR INPUT AS #FF
  90.     WHILE ((LineCount < UBOUND(FileNames$)) AND (NOT EOF(FF)))
  91.         LINE INPUT #FF, rl$
  92.         'skip the temp file...
  93.         IF rl$ <> "$_TeMP_FILE_LIST" THEN
  94.             FileNames$(LineCount) = rl$
  95.             LineCount = LineCount + 1
  96.         END IF
  97.     WEND
  98.     CLOSE #FF
  99.  
  100.     'KILL "$_TeMP_FILE_LIST"
  101.     IF INSTR(_OS$, "LINUX") THEN
  102.         SHELL _HIDE "rm $_TeMP_FILE_LIST"
  103.     ELSE
  104.         SHELL _HIDE "del $_TeMP_FILE_LIST"
  105.     END IF
  106.  
  107.  
  108.     'draw a box
  109.     COLOR _RGB(100, 100, 255)
  110.     FOR l = 0 TO y2 + 1
  111.         LOCATE y + l, x: PRINT STRING$(x2 + 4, CHR$(219));
  112.     NEXT
  113.  
  114.     'show current working dir
  115.     COLOR _RGB(255, 255, 255), _RGB(100, 100, 255)
  116.     CurDir$ = _CWD$
  117.     'Shorten it is too long, for display purposes
  118.     IF LEN(CurDir$) > x2 - x THEN
  119.         CurDir$ = MID$(CurDir$, 1, x2 - x - 3) + "..."
  120.     END IF
  121.     LOCATE y, x + 2: PRINT CurDir$;
  122.  
  123.     DO
  124.  
  125.         FOR l = 0 TO (y2 - 1)
  126.             LOCATE (y + 1) + l, (x + 2)
  127.             IF l + top = selection THEN
  128.                 COLOR _RGB(0, 0, 64), _RGB(255, 255, 255) 'selected line
  129.             ELSE
  130.  
  131.                 COLOR _RGB(255, 255, 255), _RGB(0, 0, 64) 'regular
  132.  
  133.                 'directories get a different color...
  134.                 IF MID$(FileNames$(top + l), 1, 1) = "[" THEN
  135.                     COLOR _RGB(255, 255, 0), _RGB(0, 0, 64)
  136.                 END IF
  137.             END IF
  138.             PRINT LEFT$(FileNames$(top + l) + STRING$(x2, " "), x2);
  139.         NEXT
  140.  
  141.         k$ = INKEY$
  142.         SELECT CASE k$
  143.             CASE IS = CHR$(0) + CHR$(72) 'Up arrow
  144.                 IF selection > 0 THEN selection = selection - 1
  145.                 IF selection < top THEN top = selection
  146.             CASE IS = CHR$(0) + CHR$(80) 'Down Arrow
  147.                 IF selection < (LineCount - 1) THEN selection = selection + 1
  148.                 IF selection > (top + (y2 - 2)) THEN top = selection - y2 + 1
  149.             CASE IS = CHR$(0) + CHR$(73) 'Page up
  150.                 top = top - y2
  151.                 selection = selection - y2
  152.                 IF top < 0 THEN top = 0
  153.                 IF selection < 0 THEN selection = 0
  154.             CASE IS = CHR$(0) + CHR$(81) 'Page Down
  155.                 top = top + y2
  156.                 selection = selection + y2
  157.                 IF top >= LineCount - y2 THEN top = LineCount - y2
  158.                 IF top < 0 THEN top = 0
  159.                 IF selection >= LineCount THEN selection = LineCount - 1
  160.             CASE IS = CHR$(0) + CHR$(71) 'Home
  161.                 top = 0: selection = 0
  162.             CASE IS = CHR$(0) + CHR$(79) 'End
  163.                 selection = LineCount - 1
  164.                 top = selection - y2 + 1
  165.                 IF top < 0 THEN top = 0
  166.             CASE IS = CHR$(27) ' ESC cancels
  167.                 FileSelect$ = ""
  168.                 EXIT DO
  169.             CASE IS = CHR$(13) 'Enter
  170.                 'go up one dir
  171.                 IF RTRIM$(FileNames$(selection)) = ".." THEN
  172.                     cd$ = _CWD$
  173.                     cd$ = LEFT$(cd$, _INSTRREV(cd$, "\"))
  174.                     CHDIR cd$
  175.                     ERASE FileNames$
  176.                     GOTO loadagain
  177.                 END IF
  178.                 'see if directory
  179.                 test$ = RTRIM$(FileNames$(selection))
  180.                 IF LEFT$(test$, 1) = "[" THEN
  181.                     test$ = MID$(test$, 2, LEN(test$) - 2)
  182.                     CHDIR test$
  183.                     ERASE FileNames$
  184.                     GOTO loadagain
  185.                 ELSE
  186.                     IF RIGHT$(_CWD$, 1) = "\" THEN
  187.                         C$ = _CWD$
  188.                     ELSE
  189.                         C$ = _CWD$ + "\"
  190.                     END IF
  191.                     FileSelect$ = C$ + RTRIM$(FileNames$(selection))
  192.                     EXIT DO
  193.                 END IF
  194.         END SELECT
  195.     LOOP
  196.  
  197.     _KEYCLEAR
  198.  
  199.     '=== Restore the whole screen
  200.     _MEMCOPY scr2, scr2.OFFSET, scr2.SIZE TO scr1, scr1.OFFSET
  201.     _MEMFREE scr1: _MEMFREE scr2
  202.  
  203.     '=== restore original y,x
  204.     LOCATE origy, origx
  205.  
  206.     COLOR fg&, bg&
  207.  
  208.  

Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: bplus on February 05, 2021, 10:07:30 pm
Steve advised me one time to use one filename stored under Windows temp folder from environment variable.

Just write over that file, no need to kill, kill, kill unless you just like saying that to Windows.

I like your one box method everything in one window, Tiny Navigator is going to be rid of that pesky need to press f to select from files listing. Simple solutions often the best!
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: Dav on February 05, 2021, 10:51:04 pm
That's a good thought, @bplus.  I'm not sure in Linux has a environment temp setting though, but perhaps I can do the one temp file in the programs _STARTDIR$ directory instead, that would bypass writing temp files in every directory browsed and writing any to restricted directories too.  Thanks for the idea. 

- Dav
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: bplus on February 05, 2021, 10:57:12 pm
That's a good thought, @bplus.  I'm not sure in Linux has a environment temp setting though, but perhaps I can do the one temp file in the programs _STARTDIR$ directory instead, that would bypass writing temp files in every directory browsed and writing any to restricted directories too.  Thanks for the idea. 

- Dav

Well I thought when you were going to go for cross platform, you'd use the direntry.h method.

I know you wrote that somewhere, were you just teas'n me?  ;-))
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: Dav on February 05, 2021, 11:02:57 pm
I'll be using direntry, but I wanted to get this method figured out.  One of my quirks I guess, can't let things go very easy while they're still gnawing on me.

- Dav
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: bplus on February 05, 2021, 11:08:57 pm
I'll be using direntry, but I wanted to get this method figured out.  One of my quirks I guess, can't let things go very easy while they're still gnawing on me.

- Dav

Yeah, I know that.

But I'm saying don't worry what Linux does about temp files, you would be switching to the other method by then I would think.
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: SpriggsySpriggs on February 05, 2021, 11:10:58 pm
Might I suggest using pipecom to get rid of using temp files? There will be a speed increase and will work on all platforms still
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: bplus on February 05, 2021, 11:16:19 pm
Oh man I just remembered an advantage with temp files, you can get all kinds of details about the files too and might be easier to do pathed-file-spec.

@SpriggsySpriggs  I have that pipecom code of yours, offhand I don't remember if it can do all the details like a Command prompt Dir with all the switches can do. What do you say?

Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: SpriggsySpriggs on February 05, 2021, 11:19:43 pm
@bplus It will do any command. It simply returns console output. Anything you want. It can replace any SHELL. Its main advantage is speed and immediate filling of a variable rather than writing to a file, opening it, reading it, closing it, deleting it.
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: bplus on February 05, 2021, 11:22:28 pm
Well I will check it out again, do you happen to have a link?
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: SpriggsySpriggs on February 05, 2021, 11:25:43 pm
@bplus Click my link in my signature for my API Collection, click the GitHub link on that page and then navigate to the Cross Platform folder. It's in there.
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: bplus on February 06, 2021, 12:39:03 am
@Dav  have you seen Doppler's method?

Code: QB64: [Select]
  1.  
  2. Shell "dir /b *.* | clip"
  3.  
  4.  
  5.  

0 temp files!!!
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: bplus on February 06, 2021, 12:42:40 am
OK @SpriggsySpriggs

I found this that requires much less digging:
https://www.qb64.org/forum/index.php?topic=3167.msg124332#msg124332

Code: QB64: [Select]
  1. _Title "Dir replacement " ' >>>>>>>>>>>>>> needs pipecom.h in QB64 folder
  2. 'spriggsySpriggs ref:  https://www.qb64.org/forum/index.php?topic=3167.msg124332#msg124332
  3.  
  4. ' the following is the pipecom.h file without comments
  5.  
  6. 'const char* pipecom (char* cmd){
  7. 'string data;
  8. 'FILE * stream;
  9. 'const int max_buffer = 256;
  10. 'char buffer[max_buffer];
  11.  
  12. '    stream = popen(cmd, "r");
  13. '    if (stream) {
  14. '        while (!feof(stream)) {
  15. '            if (fgets(buffer, max_buffer, stream) != NULL) {
  16. '                data.append(buffer);
  17. '            }
  18. '        }
  19. '        pclose(stream);
  20. '    }
  21. '    //
  22. '    //cout << data;
  23. '    const char* dataout;
  24. '    dataout = strdup(data.c_str());
  25. '    return dataout;
  26. '}
  27.  
  28.  
  29.  
  30. Declare Library "pipecom"
  31.     Function pipecom$ (cmd As String)
  32.  
  33.  
  34. ' NOTE: these slants work \    these do not /
  35. 'F = pipecom("dir C:/*.*") ' Linux needs other switches
  36. F = pipecom("dir /b *.BAS") 'if you need just the filenames and not the rest of the output
  37.  
  38.  
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: Dav on February 06, 2021, 09:52:02 am
Oh cool. I see I had that pipcom downloaded already, forgot about it.  Nice one.

Really slick trick, doppler's method.

- Dav
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: SpriggsySpriggs on February 06, 2021, 10:18:44 am
@Dav the main thing though is that using clip slows down shell execution by quite a bit. At that point you should use temp files because that's quicker than clip.
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: Dav on February 06, 2021, 11:42:06 am
Yes, good point. @SpriggsySpriggs.

- Dav
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: bplus on February 06, 2021, 01:27:11 pm
Can't be that great a difference reading/writing files to disk is slower than access to Clips stored in RAM, I would think.
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: SpriggsySpriggs on February 06, 2021, 01:29:38 pm
@bplus I'm talking about using clip. When you pipe to clip it takes a lot longer than just writing to a file. The clipboard itself isn't slow. It's the usage of clip that is.
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: bplus on February 06, 2021, 01:39:25 pm
Are you saying you can't get access to clip data faster than you can get access file data?
Is clip data written to temp files on disk by OS, that would be an explanation about access being slower for clip but seems not very smart coding. Send Steve over and show them how to use memory ;-))


Quote
It's the usage of clip that is.
The usage of the data is up to us in our QB64 code.
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: bplus on February 06, 2021, 01:54:19 pm
Oh it's probably the SHELL that's slower than pipecom.
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: SpriggsySpriggs on February 06, 2021, 02:02:33 pm
Are you saying you can't get access to clip data faster than you can get access file data?
Is clip data written to temp files on disk by OS, that would be an explanation about access being slower for clip but seems not very smart coding.

@bplus You aren't understanding what I am saying. "clip" is a command in command prompt. The action of piping "dir" or whatever into "clip" is what takes extra time because now you are calling two commands rather than one. The clipboard itself is fine. What you are doing in "dir | clip" is telling it to run "dir" and then send everything from "dir" into the command "clip" which THEN fills the clipboard. That's slow. That command is running TWO executables. "clip" is reading the stdout handle of "dir" and then writing to the clipboard. When you write straight to a file you aren't having to worry about running a second executable. That time spent is saved. WinAPI has functions for making temp files out in a temp directory and they work great.

Oh it's probably the SHELL that's slower than pipecom.

I've been saying that SHELL is slower than pipecom for months now. But it isn't JUST the SHELL that's slower here. The "clip" command makes it way slower than pipecom and even slower than using files. Use temp files instead of "clip".
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: bplus on February 06, 2021, 04:30:31 pm
OK working with what pipecom returns people should know it is Chr$(10) delimited string should they want to split the string into an array.

Also it appears an empty string$ = "" is on the end, don't know if that is from pipecom probably or the split I am using?
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: SpriggsySpriggs on February 06, 2021, 04:34:34 pm
Probably the split you are using. Before in the past I've had to do UBOUND(array)-1. And they can always look at the C++ code to see how it is delimited. I opted for Linux style which is CHR$(10) rather than Windows style which is CHR$(13) + CHR$(10).

Which split are you using? I've had issues before with splitting strings because of the algorithms that are out there. I haven't found one I really like just yet.
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: bplus on February 06, 2021, 05:09:02 pm
Probably the split you are using. Before in the past I've had to do UBOUND(array)-1. And they can always look at the C++ code to see how it is delimited. I opted for Linux style which is CHR$(10) rather than Windows style which is CHR$(13) + CHR$(10).

Which split are you using? I've had issues before with splitting strings because of the algorithms that are out there. I haven't found one I really like just yet.

Quote
I opted for Linux style which is CHR$(10) rather than Windows style which is CHR$(13) + CHR$(10).
Oh is this built into the .h file? I approve! not that it matters :)
I consider the 2 byte delimiter the old DOS way and Chr$(10) the newer way, only 1 byte is more efficient.

Quote
Before in the past I've had to do UBOUND(array)-1
Don't you think this indicates an empty string on the end, I am wondering about a Chr$(0) on the end since C likes to do that. Anyway there is something useless at that Ubound.

Split1000 found here:
https://www.qb64.org/forum/index.php?topic=1607.msg108201#msg108201
I am getting perfect counts in my tests of a simple array displayer and my arrays coming out of Split have some empty string character at Ubound of array. Maybe if I trimmed the returned string from pipecom? maybe I should just check that next, before the splitting. ;-))

It handles 0 and 1 base ReDim 'd arrays (dynamic that you can change the size of) it probably could handle an exotic
Code: QB64: [Select]
  1. ReDim(-5 to -5) as string
but I have enough things to test and play with.

I will show you the code when I am done messing with it. I am really interested in the ideal way to do files and folders cross platform. But I suspect ideal depends on the application as usual. So my app is get a filename or pathname from anywhere on hard drive. After that selecting multiple files from different folders for some operation like copy to SD drive maybe for my backups.
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: SpriggsySpriggs on February 06, 2021, 05:13:24 pm
Don't you think this indicates an empty string on the end, I am wondering about a Chr$(0) on the end since C likes to do that. Anyway there is something useless at that Ubound.

I take it back.... I remember that sometimes (depending on the command) you might have an extra CHR$(10). You can use LEFT$ or MID$ and just take it off.
Title: Re: Question about using SHELL "dir" on non windows OS.
Post by: bplus on February 07, 2021, 02:02:35 am
Yes at the end of the string returned by pipecom is a delimiter, to be ignored.

I got a crude browser working using pipecom to get a dir listing to navigate with:
Code: QB64: [Select]
  1. _Title "Compare Pipecom to SHELL methods of file data access" 'b+ 2021-02-6
  2. Screen _NewImage(1024, 400, 32)
  3. _Delay .25
  4.  
  5. Declare Library "pipecom"
  6.     Function pipecom$ (cmd As String)
  7.  
  8. 'Dim F As String                 'tests with command line dir calls
  9. ' NOTE: these slants work \    these do not /
  10. 'F = pipecom("dir " + Chr$(34) + "C:\users\marka\desktop\QB64 work\000 work QB64" + Chr$(34) + " /b /A:D") ' Linux needs other switches
  11. 'F = pipecom("dir /b *.BAS") 'if you need just the filenames and not the rest of the output
  12. 'F = pipecom("dir /b /A:D") ' /b = bare list /A:D directories only
  13. 'F = pipecom("dir /n /o:gend") ' long list files on right? well <dir> for dirs and files  ahhhh!
  14.  
  15. ReDim As String choice
  16. While _KeyDown(27) = 0 'until escape
  17.     choice = GetFileName$
  18.     If choice <> "" Then Print: Print "You selected " + choice Else Print: Print "You canceled"
  19.     Print: Print "          press any for another test, escape to quit..."
  20.     Sleep
  21.  
  22. Function GetFileName$ ()
  23.     Dim As String d, s, dr
  24.     Getfolder:
  25.     d = pipecom("dir /n /o:gend") '/n files on right (40) /o = order g for group dirs first, e extension, name, date
  26.     d = Left$(d, Len(d) - 1) ' always ends with delimiter
  27.     ReDim dir$(1 To 1)
  28.     Split d, Chr$(10), dir$()
  29.     s$ = GetArrayItem$(dir$())
  30.     Cls
  31.     If InStr(s$, "<DIR>") Then 'isolate name
  32.         dr$ = _Trim$(Mid$(s$, InStr(s$, "<DIR>") + 6))
  33.         ChDir dr$
  34.         GoTo Getfolder
  35.     ElseIf InStr(s$, "AM") Or InStr(s$, "PM") Then
  36.         GetFileName$ = _Trim$(Mid$(s$, 40))
  37.     End If
  38.  
  39. Sub Split (SplitMeString As String, delim As String, loadMeArray() As String)
  40.     Dim curpos As Long, arrpos As Long, LD As Long, dpos As Long 'fix use the Lbound the array already has
  41.     curpos = 1: arrpos = LBound(loadMeArray): LD = Len(delim)
  42.     dpos = InStr(curpos, SplitMeString, delim)
  43.     Do Until dpos = 0
  44.         loadMeArray(arrpos) = Mid$(SplitMeString, curpos, dpos - curpos)
  45.         arrpos = arrpos + 1
  46.         If arrpos > UBound(loadMeArray) Then ReDim _Preserve loadMeArray(LBound(loadMeArray) To UBound(loadMeArray) + 1000) As String
  47.         curpos = dpos + LD
  48.         dpos = InStr(curpos, SplitMeString, delim)
  49.     Loop
  50.     loadMeArray(arrpos) = Mid$(SplitMeString, curpos)
  51.     ReDim _Preserve loadMeArray(LBound(loadMeArray) To arrpos) As String 'get the ubound correct
  52.  
  53. Function GetArrayItem$ (arr() As String)
  54.     Dim As Long lb, ub, top, i, row, prevrow, n, ad, r
  55.     Dim iNum$, k$
  56.     lb = LBound(arr): ub = UBound(arr): ad = _AutoDisplay
  57.     If ub - lb + 1 < 21 Then top = ub Else top = lb + 19
  58.     Do
  59.         Cls
  60.         Print "       Scroll, Enter number choice, delete to Clear number, or escape to Cancel"
  61.         If ub - lb + 1 > 20 Then
  62.             While _MouseInput
  63.                 row = row + _MouseWheel
  64.                 If row < lb Then row = lb 'prevent under scrolling
  65.                 If row > ub - 19 Then row = ub - 19 'prevent over scrolling
  66.                 If prevrow <> row Then 'look for a change in row value
  67.                     prevrow = row 'store previous row valu
  68.                 End If
  69.             Wend
  70.             r = 2
  71.             For n = row To row + 19
  72.                 Locate r, 1: Print "#"; _Trim$(Str$(n)); ": "; " "; arr(n)
  73.                 r = r + 1
  74.             Next
  75.         Else
  76.             For i = lb To top
  77.                 Print i; " "; arr(i)
  78.             Next
  79.         End If
  80.         Locate 23, 1: Print iNum$
  81.         k$ = InKey$
  82.         If InStr("0123456789", k$) Then
  83.             iNum$ = iNum$ + k$
  84.         ElseIf iNum$ = "" And k$ = "-" Then
  85.             iNum$ = "-"
  86.         ElseIf k$ = Chr$(8) Then
  87.             If Len(iNum$) Then iNum$ = Left$(iNum$, Len(iNum$) - 1)
  88.         ElseIf Len(k$) = 2 And Right$(k$, 1) = Chr$(83) Then
  89.             iNum$ = ""
  90.         ElseIf k$ = Chr$(13) And Len(iNum$) Then
  91.             If Val(iNum$) >= lb And Val(iNum$) <= ub Then GetArrayItem$ = arr(Val(iNum$)): Exit Do Else iNum$ = ""
  92.         ElseIf k$ = Chr$(27) Then
  93.             Exit Function
  94.         End If
  95.         _Display
  96.         _Limit 30
  97.     Loop
  98.     If ad Then _AutoDisplay ' reverse changes
  99.     _KeyClear
  100.