Decision code
Pages: 1 2
Richard Ashbery (495) 163 posts |
I have an application that contains a directory called Store which contains a Drawfile. Two routines are used to (a) load the Drawfile into memory (code below) and (b) open a window and render it to screen (requiring parameters… Drawfile and length%). DEF PROCDealWith_InitialEvent DEF PROCLoadFile(file$) As it stands it renders a Drawfile providing the name is Drawfile. Has anyone a BASIC routine to… 1. Check if Drawfile and reject it if not. I don’t think this will require anyone with experience of AppBasic since example is a self contained routine to load the Drawfile into memory. Duplicated on c.s.a.programmer. |
Steve Fryatt (216) 2105 posts |
Firstly, you don’t want to be using OS_File 20 as that’s the one which uses File$Path to locate the supplied filename. You want OS_File 23, which is equivalent, but doesn’t mess with the filename at all. To reject non-drawfiles, just check the returned type and reject anything that isn’t &AFF (which is the drawfile type). I think this is returned in R6 by OS_File 20-23, but the ROOL Wiki PRM has what looks to be the wrong list of exit registers for the call and I don’t have any other documentation to check against at the moment – if anyone else can confirm or correct, please do! DEF PROCLoadFile(file$) SYS “OS_File”,23,file$ TO ,,,,length%,,type% IF type% <> &AFF THEN ENDPROC DIM drawfile length% SYS “OS_File”,12,file$,drawfile ENDPROC To load any files from the folder, you’ll need to scan the contents and process any with drawfile type. You can do that with OS_GBPB, although it isn’t necessarily straightforward. Both of the following examples are untested! OS_GBPB 12 will do it: DEF PROCLoadFiles(folder$) LOCAL next%, read%, buffer% DIM buffer% LOCAL 255 next% = 0 REPEAT SYS "OS_GBPB", 12, folder$, buffer%, 1, next%, 256, 0 TO ,,,read%, next% IF read% > 0 THEN IF buffer%!16 = 1 AND buffer%!20 = &AFF THEN SYS "XOS_GenerateError", buffer% + 24 TO filename$ REM Now load folder$ + "." + filename$ ENDIF ENDIF UNTIL next% = 0 ENDPROC You can fill in the comment! Note that the DIM LOCAL makes this code RISC OS 5 only: you’ll need a static buffer somewhere if you need it to work on other flavours of BASIC. Usefully, OS_GBPB 12 isn’t supported by all filing systems. For more general support, you need OS_GBPB 10, which doesn’t do filetypes as easily. DEF PROCLoadFiles(folder$) LOCAL next%, read%, type%, buffer% DIM buffer% LOCAL 255 next% = 0 REPEAT SYS "OS_GBPB", 10, folder$, buffer%, 1, next%, 256, 0 TO ,,,read%, next% IF read% > 0 THEN IF (buffer%!0 AND &FFF00000) = &FFF00000 THEN type% = (buffer%!0 AND &000FFF00) >> 8 ELSE type% = -1 ENDIF IF buffer%!16 = 1 AND type% = &AFF THEN SYS "XOS_GenerateError", buffer% + 20 TO filename$ REM Now load folder$ + "." + filename$ ENDIF ENDIF UNTIL next% = 0 ENDPROC |
Richard Ashbery (495) 163 posts |
Thanks for coming back Steve. I’ll study your reply and get back to you. I have to admit the code I showed is not mine – as you can work out it was ‘ripped’ from Joe Taylor – at least I think it was his. |
Rick Murray (539) 13851 posts |
And, don’t forget that if you want to examine “unknown” files to see if they are DrawFiles, that too is easy. Simply load the first four bytes of the file and see if it says “Draw” (or, as a word, &57415244). An empty DrawFile created by the RISC OS 5 version of !Draw is 128 bytes; so you can probably automatically reject anything that is smaller than that. It also appears that DrawFiles are entirely word aligned (tested on five random DrawFiles on my machine) so you may also be able to reject any file with a size that isn’t exactly divisible by 4 – though it may be better to await confirmation of this. |
Richard Ashbery (495) 163 posts |
Reference your first example…
Running this as a standalone program with a Drawfile in the same directory recognises the Drawfile but I get a syntax error at the line… LOAD folder$+ “.” +filename$ Does the LOAD statement look correct? If so I must have an issue elsewhere in the program. |
Rick Murray (539) 13851 posts |
His code actually says: REM Now load folder$ + "." + filename$ At this point, you will need to supply the code to actually perform the file load. Steve has provided an example function, LOAD keyword is for loading (and not immediately running) BASIC programs.
|
Richard Ashbery (495) 163 posts |
Ahh! Rick you’ve correctly pointed out that there is no internal BASIC keyword for LOAD. You also advised I should use the routine (PROCLoadFile(file$)) to load the Drawfile at the beginning of Steve’s posting which I have reposted below so that folks can see what I am attempting to do but… Annoyingly I can’t get to the Drawfile loading stage because I’m getting a message stating Store.Drawfile is a file at line xxx from the line… SYS “OS_GBPB”, 12, folder$, buffer%, 1, next%, 256, 0 TO ,,,read%, next% According to the StrongHelp os336 manual Steve’s parameters look correct. On removing Drawfile I get a message not found at line xxx. Why it reports the obvious is a complete mystery? Any thoughts as to what to do next? ON ERROR REPORT:PRINT " at line “;ERL:END DEF PROCLoadFile(file$) • Program set as a stand-alone program in a directory, 4 directories deep. |
Chris Johnson (125) 825 posts |
Richard – you are misunderstanding the operation of the OS_GBPB call. Folder$ must point to the folder in which your files of interest are. Thus it should point to Store. The Repeat Until loop then iterates through all the files within that directory. The rest of the code in the loop will check the filetype of each file, and if it is a drawfile, will extract the filename. One question – why is there an END after the PROCload call? This will surely terminate the program as soon as the file is loaded – not all that helpful. Also you are extracting the file name to the variable filename$ but then loading the file held in file$. |
Steve Drain (222) 1620 posts |
Of course, and it can only be used at the command line. But with Basalt it does load files into memory:
Which loads the file at the address, checking that it will fit if the size is given, and checking that the filetype is in the list of types following OF, if present An unpublished variant is:
Which claims memory for the file before loading it. |
Chris Johnson (125) 825 posts |
Just to add – the filename extracted into filename$ will be the actual leafname of the file, so you will need to construct the full path to pass to PROCloadfile, otherwise you will get a ‘File not found’ error. |
Steve Drain (222) 1620 posts |
And why is there not an END before the DEFs? Dropping through from the program might be causing a problem. |
Fred Graute (114) 645 posts |
This needs to be:
|
Richard Ashbery (495) 163 posts |
My latest effort lets me perform the iterative search, checking filetype and extracting filename if it finds a Drawfile correctly. Thanks Chris for telling me how it works and to Fred who pointed out – PROC won’t work unless UNTIL next% is changed from 0 to -1. It now then hangs on the second PROC with DrawFile not found at line 240 which is what you warned me about Chris.
I’m still blissfully ignorant as to how to do this – example required please. 10 ON ERROR REPORT:PRINT " at line ";ERL:END 20 PROCLoadFiles(“SDFS::RISCOSpi.$.Store”) 30 END 40 : 50 DEF PROCLoadFiles(Folder$) 60 LOCAL next%, read%, buffer% 70 DIM buffer% LOCAL 255 80 next% = 0 90 REPEAT 100 SYS “OS_GBPB”, 12, Folder$, buffer%, 1, next%, 256, 0 TO ,,,read%, next% 110 IF read% = 0 THEN 120 IF buffer%!16 = 1 AND buffer%!20 = &AFF THEN 130 SYS “XOS_GenerateError”, buffer% + 24 TO filename$ 140 PROCLoadFile(filename$) 150 ENDIF 160 ENDIF 170 UNTIL next% = -1 180 ENDPROC 190 : 200 DEF PROCLoadFile(filename$) 210 SYS “OS_File”,23,filename$ TO ,,,,length%,,type% 220 IF type% <> &AFF THEN ENDPROC 230 DIM drawfile length% 240 SYS “OS_File”,12,filename$,drawfile 250 ENDPROCIn answer to Steve Drain and Chris – the END keyword after the PROCload call was an error. It was in the correct position originally before the DEF PROCs but having messed about so much I’ve inadvertently moved it. |
Colin (478) 2433 posts |
Start your code with ‘bc.. ’ at the beginning of the line (without the ’’ marks and note the trailing space.) then end it with a blank line followed by ’p. ’. the code should now be formatted correctly like this:
If there are no blank lines as in the above you can get away with just starting the first line with ’bc. ’ and forgetting about the ’p. ’ |
Richard Ashbery (495) 163 posts |
Line numbers screw up listing. Here it is without. Line 240 is the last line but one. ON ERROR REPORT:PRINT " at line “;ERL:END |
Richard Ashbery (495) 163 posts |
Thanks for the formatting tip Colin. |
Fred Graute (114) 645 posts |
You need to pass the path of the file to PROCLoadFile:
The call to OS_File in PROCLoadFile is not necessary as OS_GBPB,12 already returns the object size in buffer% + 8. Hence:
IIRC you’re using AppBasic in which case I’d suggest starting function names with an underscore to prevent clashes with AppBasic function names. Also, you can use FNUtils_String(addr%) to read strings from buffers instead of XOS_GenerateError. |
Richard Ashbery (495) 163 posts |
Thanks for your posting Fred. OK – I think I have a slightly better idea what Steve, Chris and you mean about… PROCLoadFile(folder$ + “.” + filename$) As a stand-alone program your modifcations seem to work – I need to test it properly by adding some way of loading the Drawfile from memory to Draw. AppBasic doesn’t like… PROCLoadFile(folder$ + “.” + filename$, buffer%!8) Leaving buffer%!8 off makes no difference either. Maybe underscoring the starting function names to prevent a clash with AppBasic’s function names is the way to go. It just gets more complicated :-( |
Fred Graute (114) 645 posts |
Not sure why AppBasic is complaining, it should work. Could it be that you copied the code from the forum and were tricked by the sexed quotes? I created a quick app using AppBasic and added the code to an iconbar click, and it works. Read the app’s memory using StrongED to make sure and the drawfile was there. Here’s my iconbar handler:
|
Richard Ashbery (495) 163 posts |
No. I’ve been caught by that one before so always look to see if sexed quotes are present in the BASIC. Reference your example. I have set up a new BasicApp using it and it works without error. This indicates I may still have error(s) in my Initial event-handler. I will go through it with a fine tooth-comb. Thanks for providing a complete working example. |
GavinWraith (26) 1563 posts |
Misplaced hyphen. I think you mean fine-tooth comb. |
Steve Pampling (1551) 8172 posts |
Or Richard is experiencing one of those morning after situations where you’re sure your teeth have fur. |
Richard Ashbery (495) 163 posts |
My app. to date loads a Drawfile from a directory – Store and displays it using Steve Fryatts SWI OS_GBPB 12 in a Window handler. AppBasic’s built-in Drawing handler will display it. I’ve added a DataImport routine which enables me to drag a new Drawfile from a filer window over the main window or iconbar icon which overwrites the existing Drawfile in the Store directory. My problem is : how do I force the app. to display the new Drawfile? |
Chris Hall (132) 3559 posts |
Just call SYS “Wimp_ForceRedraw” specifying the area that has changed. The Wimp will then send your app a redraw instruction for any affected rectangles via Wimp_Poll. |
Colin (478) 2433 posts |
Oops wrong thread |
Pages: 1 2