\ Parse filenames
:noname ( -- )
argv 0= if help then \ no args
s" SCR" +ext 2dup ifile !fname \ got 1st apply default src ext
-path -ext \ keep body
argv if \ got 2nd
2dup -ext nip while \ has body
2nip then s" LST" \ default dest ext
else 1 /string then +ext \ trim '.' from user ext
ofile !fname ; is parsefn
\\ Samples
foo. --> foo. foo.lst
foo --> foo.scr foo.lst
foo bar. --> foo.scr bar.
foo bar --> foo.scr bar.lst
foo .prn --> foo.scr foo.prn
foo. . --> foo. foo. (same: caught later)
ARGV ( -- a u -1 | 0 ) get next blank delimited argument
+EXT ( a1 u1 a2 u2 -- a3 u3 ) append ext a2/u2 to fname if '.' not present >-EXT ( a1 u1 -- a1 u2 ) discard extension from filename
-PATH ( a1 u1 -- a2 u2 ) discard path from filename
$/ ( "dollar slash" )
STACKEFFECT: sc c --- sc1 sc2
DESCRIPTION:
Find the first c in the string constant sc and split it at that address. Return the strings after and before c into sc1 and sc2 respectively.
If the character is not present sc1 is a null string (its address is zero) and
sc2 is the original string.
Both sc1 and sc2 may be empty strings (i.e. their count is zero),
if c is the last or first character in sc .
none wrote:
[..]
$/ ( "dollar slash" )
STACKEFFECT: sc c --- sc1 sc2
DESCRIPTION:
Find the first c in the string constant sc and split it at that address.
Return the strings after and before c into sc1 and sc2 respectively.
If the character is not present sc1 is a null string (its address is zero) and
sc2 is the original string.
Both sc1 and sc2 may be empty strings (i.e. their count is zero),
if c is the last or first character in sc .
I use Wil Baden's Split-At-Char
FORTH> locate Split-At-Char
File: d:\dfwforth/include/miscutil.frt
1323:
1324: -- Wil Baden
1325: -- Right string starts with delimiter
1326>> : Split-At-Char ( addr1 n1 char -- addr1 n2 addr1+n2 n1-n2 )
Note that the delimiter is NOT deleted: it is at the front of the right >string. This is a nuisance sometimes (even more for Split-At-LastChar).
Your method returns two empty strings for the cases where I would expect
the original to be returned (sc1 when the delimiter is the last char,
sc2 when the delimiter is the first char). Therefore a copy must be made >before the split if more processing follows?
-marcel--
Using $\ to split the extension from the filename is not without quirks.
If '.' is not present it thinks the whole filename is the extension.
My parser also requires a '.' in the filename; however that's to prevent
it auto-appending the default extension.
dxf wrote:
Using $\ to split the extension from the filename is not without quirks.
If '.' is not present it thinks the whole filename is the extension.
My parser also requires a '.' in the filename; however that's to prevent
it auto-appending the default extension.
A minor issue is that $\ "string-split" is the wrong name for the word
as it does more than splitting: it also removes the separator.
['apple', 'banana', 'cherry', 'orange']txt = "apple#banana#cherry#orange"
x = txt.split("#")
print(x)
That aside, I was curious if removing the separator was more convenientPlease stick to the terminology introduced. There is a distrinction
than leaving it in. I examined my usage and in many cases there is a
check for 0-length and in many others the separator is removed
(problematic because a 0-string may result).
Apart from the separator being first or last, there are also the casesA separator can separate empty strings. Read the specification carefully.
that the separator appears more than once: "a/pe/kool" or is duplicated >"//apekool" (where the separator is '/').
-marcelGroetjes Albert
On 29/01/2024 12:49 am, albert wrote:
...
Let's have ARG[] that isolates the nth argument and the usual
$! $@ $/ @+! $\ $+C wordset
`lina -c /tmp/aap.frt' now creates `/tmp/aap' as executable.
1 ARG[] &. $\ 2DROP PAD $! ( or use it as is)
`wina -c /tmp/aap.frt' now creates `/tmp/aap.EXE' as executable.
1 ARG[] &. $\ 2DROP "EXE" PAD $+! PAD $!
No need to invent a special parser.
Here's a real world command-line. Please provide your code for
processing it.
BLK2TXT version 1.5
Use: BLK2TXT [-opt] file[.SCR] [file[.LST]]
Even this wasn't sufficiently convenient for me as an end-user,
hence my post.
On 29/01/2024 8:59 pm, albert@spenarnc.xs4all.nl wrote:
In article <up6t35$4u0i$1@dont-email.me>, dxf <dxforth@gmail.com> wrote: >>> On 29/01/2024 12:49 am, albert wrote:
I'm perfectly willing to write the code, as long as you specify...
Let's have ARG[] that isolates the nth argument and the usual
$! $@ $/ @+! $\ $+C wordset
`lina -c /tmp/aap.frt' now creates `/tmp/aap' as executable.
1 ARG[] &. $\ 2DROP PAD $! ( or use it as is)
`wina -c /tmp/aap.frt' now creates `/tmp/aap.EXE' as executable.
1 ARG[] &. $\ 2DROP "EXE" PAD $+! PAD $!
No need to invent a special parser.
Here's a real world command-line. Please provide your code for
processing it.
BLK2TXT version 1.5
Use: BLK2TXT [-opt] file[.SCR] [file[.LST]]
Even this wasn't sufficiently convenient for me as an end-user,
hence my post.
what has to be done.
What is unclear - an arbitrary number of switches typically followed
by one or two filenames. It's the basis of many a CLI application.
You say it's easily done using ARG[] and a few string operators. I
don't really see how but if someone has practical working code that >demonstrates, please do.
On 31/01/2024 10:05 pm, albert@spenarnc.xs4all.nl wrote:
In article <up9jrn$m02m$1@dont-email.me>, dxf <dxforth@gmail.com> wrote: >>> On 29/01/2024 8:59 pm, albert@spenarnc.xs4all.nl wrote:
The first thing to do is insert an intermediate abstraction layer,...I'm perfectly willing to write the code, as long as you specify
what has to be done.
What is unclear - an arbitrary number of switches typically followed
by one or two filenames. It's the basis of many a CLI application.
You say it's easily done using ARG[] and a few string operators. I
don't really see how but if someone has practical working code that
demonstrates, please do.
borrowed from c.
This ensures that everything past the first layer is portable
between Linux , MS-Windows or whatever os you want to use.
Note that splitting strings is handled in this layer.
We must admit that the API designs of c is brilliant;
Forth essentially copied the whole file wordset from c.
( n) ARG[] : a string containing the nth argument
SHIFT-ARGS : consume the first argument
ARGC : the remaining number of arguments
I have handled the conversion from AAP.FRT to AAP.EXE before.
Once more SRC>EXEC is favoured that is the same API but different
implementation between OSses.
\--------------------- examples, not tested -------------
\ input file follow
: -i SHIFT-ARGS 1 ARG[] filein $! SHIFT-ARGS ;
\ output file follow
: -o SHIFT-ARGS 1 ARG[] fileout $! SHIFT-ARGS ;
\ two files follow
: -io SHIFT-ARGS 1 ARG[] filein $! SHIFT-ARGS
1 ARG[] fileout $! SHIFT-ARGS ;
: -n SHIFT-ARGS 1 ARG[] EVALUATE n ! SHIFT-ARGS ;
: -h USAGE $@ TYPE BYE ;
: -p SHIFT-ARGS 1 ARG[] SHIFT-ARGS
BASE @ >R HEX EVALUATE R> BASE !
port ! ;
\ -N handles a collating or not collating argument
\ This relies on the PREFIX word, present in ciforth.
\ -N 12 / -N12
: -N 1 ARG[]
DUP 2 = IF
SHIFT-ARGS 1 ARG[]
ELSE
2 /STRING
THEN
EVALUATE N ! SHIFT-ARGS
; PREFIX
: doit BEGIN ARGC 1 > WHILE
1 ARG[] OVER C@ &- = IF EVALUATE ELSE
ABORT" invalid input"
THEN
now-get-on-with-it
;
Note that program's can be invoked like this (linux example)
twinprimecounting `10 12 **`
counting twin primes under the boundary 1,000,000,000,000 .
Invalid options result in
-o ? ciforth ERROR # 10 : NOT A WORD, NOR A NUMBER OR OTHER DENOTATION
I do not suggest that your approach is not usable,
merely that this is better.
It's better because it uses the forth interpreter and evaluate? I don't
know how C does it, but surely it's not that?
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 475 |
Nodes: | 16 (2 / 14) |
Uptime: | 19:16:18 |
Calls: | 9,487 |
Calls today: | 6 |
Files: | 13,617 |
Messages: | 6,121,093 |