Unlike Win/DOS, breaking a filename into components is not a trivial task under Qdos/SMSQ. Is the underscore part of a sub directory or file name? Or is it a directory, or even an extension separator? The only way to tell is to try to open the file. Even then, some guesswork is required, and the result is not guaranteed.
As promised, here is a completely new and re-imagined file name parser. It does the same as the previous one: splits a complete file name into its various components; device name, directory, name and extension. It is not perfect, and can probably never be so, as to do the job properly at least part of the file name has to exist in the file system. However, here, only the device and directory need to exist, the rest can be reasonably guessed at.
As it stands, the routine with its demo harness is only SBASIC-compatible in its uncompiled form. However, it isnt hard to modify for Qdos/Minerva (+ TK2!). Turbo users will have to do things differently altogether.
The first few program lines below are merely a demonstration. To try out the program: In SMSQ/E, if you have QD with the SBAS/QD Thing installed, just load it into QD and press F10. Or you could just EXecute the program, or LRUN it from an SBASIC console.
The significance of the r.x$ parameters is to show that these are return variables only. Any value contained in them when calling the routine will be overwritten. For SuperBASIC change these to r_x$ and change the FOR loop variable i% from integer to float.
10 IF JOBID: ch = FOPEN("con"): ELSE : ch = 1 12 REPeat loop 14 CLS#ch 16 INPUT#ch; 'Enter a file name'! fnm$ 18 IF fnm$ = '': EXIT loop 20 er = ParseFnm(fnm$, dv$, fd$, fn$, fx$) 22 IF NOT er THEN 24 PRINT#ch; fnm$ 26 PRINT#ch; 'Dev:' , dv$ 28 PRINT#ch; 'Dir:' , fd$ 30 PRINT#ch; 'Name:', fn$ 32 PRINT#ch; 'Ext:' , fx$ 34 ELSE 36 PRINT#ch; 'Some error: '! er 38 END IF 40 PAUSE#ch: rem SuperBASIC: PAUSE 42 END REPeat loop 44 : 100 rem + ------------------------------------------------------------------------ + 102 rem |< New ParseFnm >| 104 rem + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 106 rem | Splits a filename into its constituent parts | 108 rem | | 110 rem | The Device name must valid! (Or test that prior to calling this!) | 112 rem | The directory must exist or it will be taken as part of file name! | 114 rem | Everything else is optional. | 116 rem | Extension (if any) is returned with leading separator | 118 rem | An extension is expected to be from 0 to 5 char long | 120 rem | | 122 rem | No dependencies | 124 rem + ------------------------------------------------------------------------ + 126 rem | V0.01, pjw, 2023 Jun 12 | 128 rem + ------------------------------------------------------------------------ + 130 : 132 DEFine FuNction ParseFnm(f$, r.v$, r.d$, r.n$, r.x$) 134 LOCal cd, i%, t%, l% 136 t% = LEN(f$): IF t% < 5: RETurn -15 138 : 140 rem Device 142 IF f$(5) <> '_': RETurn -12 144 IF NOT f$(4) INSTR '12345678': RETurn -12 146 r.v$ = f$(1 TO 5): r.d$ = '': r.n$ = '': r.x$ = '' 148 IF t% = 5: RETurn 0 150 : 152 rem Remainder 154 cd = FOP_DIR(f$): IF cd < 0: RETurn cd 156 r.d$ = FNAME$(#cd): CLOSE#cd 158 l% = LEN(r.d$) + 1 160 IF l% = 1 THEN 162 r.n$ = f$(6 TO t%) 164 ELSE 166 r.d$ = r.d$ & '_' 168 IF t% <= (l% + 5): RETurn 0 170 r.n$ = f$(l% + 6 TO t%) 172 END IF 174 : 176 rem Extension 178 l% = LEN(r.n$) 180 IF l% > 6: t% = l% - 5: ELSE : t% = 2 182 FOR i% = l% TO t% STEP -1 184 r.x$ = r.n$(i%) & r.x$ 186 IF r.n$(i%) INSTR '_.' THEN 188 r.n$ = r.n$(1 TO i% - 1) 190 RETurn 0 192 END IF 194 END FOR i% 196 r.x$ = '': RETurn 0 198 END DEFine ParseFnm 200 : 202 :