A question about the mask
#1
Huh

I tried passing *.* and *.? and similar as a string by Command$ into my program. But instead of the expected string with these three characters, I got a file listing in the form of a long string. I could also use this if...the individual file names were somehow separated. I did a parsing of the obtained string before posting this question here - everything is separated by plain space (CHR 32). This is completely unuseless for, because then you don't know if what you are reading is the continuation of the file name in which there is a space, or if it is the name of another file...
So - of course, from the start I was counting on direntry.h to give me the filenames, that works great - but - how to get the literal mask string *.* or ?????.* and so on? Having Command$ filter it out for me would only be useful if there were special ASC separators in the filenames it provides, like CHR$ 13 or ther characters (which can't be part of a filename)


Reply
#2
You can access each individual file in the COMMAND$ by using COMMAND$(n).
Code: (Select All)
For i = 1 to _CommandCount
Print Command$(i)
Next
Ask me about Windows API and maybe some Linux stuff
Reply
#3
That's great! Thanks a lot!


Reply
#4
You are very welcome. I hope that solves your issue
Ask me about Windows API and maybe some Linux stuff
Reply
#5
(03-17-2023, 05:13 PM)Petr Wrote: So - of course, from the start I was counting on direntry.h to give me the filenames, that works great - but - how to get the literal mask string *.* or ?????.* and so on?

This was already discussed in another thread.

https://staging.qb64phoenix.com/showthread.php?tid=1327

It depends very much on the operating system because it intercepts * and ? offered on its command line. This could be CMD.EXE on Windows, or the Powershell equivalent, or "bash" on Linux. Nothing could be done about it. That's why pieces of text that have any * or ? are changed into at least one filename which has neither of those characters, and more likely, it is changed into many filenames.

The filenames without * and ? are received by COMMAND$(). There is no way to get them including * and ?, because MS-DOS worked this way too. If you really, really need to get them you will have to choose substitute characters, for example plus + for stars *. Then, in your program, change the plusses to stars and process it how you want. However, the moment you change to * or ? and then try to use another system call about filenames you will be sent back to what was already discussed about the operating system's filename expansion.

"glob" could be probably disabled in Linux but it's a messy affair. A search produced this:

http://unix.stackexchange.com/questions/...ddg#388697
Reply
#6
This does some v____o or something else, no need to check for newlines or anything like that, the business is already expanded if using wildcards!

But try using + instead of * and ~ instead of ? in this example.

Code: (Select All)
$CONSOLE:ONLY
OPTION _EXPLICIT
REDIM parm(1 TO 1) AS STRING
DIM AS INTEGER v, i
DIM a$, blk$

v = 1
FOR i = 1 TO _COMMANDCOUNT
    a$ = COMMAND$(i)
    IF INSTR(a$, "+") THEN
        ReplaceString2 a$, "+", "*", 0
    ELSEIF INSTR(a$, "~") THEN
        ReplaceString2 a$, "~", "?", 0
    END IF
    parm(v) = a$
    v = v + 1
    REDIM _PRESERVE parm(1 TO v) AS STRING
NEXT

'without "console:only" the user could set this to CHR$(219) for the solid block
blk$ = CHR$(124)
FOR i = 1 TO v - 1
    PRINT "Parameter #"; i; " : "; blk$; parm(i); blk$
NEXT
SYSTEM

SUB ReplaceString2 (tx AS STRING, sfind AS STRING, repl AS STRING, numtimes AS _UNSIGNED LONG)
    DIM s AS STRING, t AS STRING, goahead AS _BYTE
    DIM AS _UNSIGNED LONG ls, count, u
    IF (tx = "") OR (sfind = "") OR (sfind = repl) OR (LEN(sfind) > LEN(tx)) THEN EXIT SUB
    s = UCASE$(sfind)
    t = UCASE$(tx)
    ls = LEN(s)
    count = 0
    goahead = 1
    DO
        u = INSTR(t, s)
        IF u > 0 THEN
            tx = LEFT$(tx, u - 1) + repl + MID$(tx, u + ls)
            t = UCASE$(tx)
            IF numtimes > 0 THEN count = count + 1: IF count >= numtimes THEN goahead = 0
        ELSE
            goahead = 0
        END IF
    LOOP WHILE goahead
END SUB
Reply
#7
Thank you very much for your help. On the contrary, it is a welcome help that Command$ saves work and returns filtered files. The above procedure with _CommandCount is excellent and perfectly fine, so I could delete my own sorting solution for the mask and rely on the output from Command$. 

I know that mask from the days of Dos, I have worked in Dos since version 5.0, I clearly remember the configurations of Autoexec.bat and Config.sys and at that time the loading of high memory managers EMM386 and Himem.sys and also the booting of CD-Rom drivers under dos it was something as mscdex.exe - something... , yeah that was fun. But there is one more question. *.* should list folders and subdirectories if I remember correctly. Command$ won't do that. Is there a trick to get those subdirectories out of it? If it doesn't work out like this, I'll take a different approach, I'm just asking. I am working on upgrading my PMF2 program.


Reply
#8
(03-18-2023, 08:56 AM)Petr Wrote: But there is one more question. *.* should list folders and subdirectories if I remember correctly. Command$ won't do that. Is there a trick to get those subdirectories out of it? If it doesn't work out like this, I'll take a different approach, I'm just asking. I am working on upgrading my PMF2 program.

It will have to be done the "direntry.h" way. (The original C header file on Linux is called "dirent.h".) I'm not familiar with it but there should be a field in the structure which helps the programmer tell if the file is a "regular" file or if it's a directory. If it's a directory then you'll have to get another list of files for that directory. It's best to keep track of directories into a string array, as they are found and, after one directory is processed for the file names it has, take it out of the array.

Might want to look at this:

https://staging.qb64phoenix.com/showthread.php?tid=68

Understandably, "*.*" is limited only to the current directory because if could involve thousands of files in subdirectories, and this could choke certain command-line programs and other programs which are not well-written.
Reply




Users browsing this thread: 2 Guest(s)