; ; currDir.s ; ; Puts the current directory in a code variable ; ; © 1994-1998 Straylight ; ;----- Licensing note ------------------------------------------------------- ; ; CurrDir is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2, or (at your option) ; any later version. ; ; CurrDir is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with CurrDir. If not, write to the Free Software Foundation, ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ;----- Standard header ------------------------------------------------------ GET libs:header GET libs:swis ;----- External dependencies ------------------------------------------------ IMPORT version IMPORT |Image$$RW$$Limit| ;----- Main code ------------------------------------------------------------ AREA |Asm$$Code|,CODE,READONLY ENTRY ; --- main --- ; ; On entry: -- ; ; On exit: Via OS_Exit ; ; Use: Installs the CurrDir variable. main ROUT ; --- Check for RISC OS 3 --- MOV R0,#129 ;Read OS version number MOV R1,#0 MOV R2,#255 SWI OS_Byte CMP R1,#&A3 ;Check for RISC OS 3 BLO cd__badOSVer ;Wrong -- make an error ; --- Parse the command line arguments --- ADRL R12,|Image$$RW$$Limit| ;Find the program end SWI OS_GetEnv ;Read the command line cd__skipLoop LDRB R14,[R0],#1 ;Get next byte from this CMP R14,#32 ;Is it the end of the name? BHI cd__skipLoop ;No -- go round again cd__spaceLoop CMP R14,#32 ;Is this a space? LDREQB R14,[R0],#1 ;Yes -- get another byte BEQ cd__spaceLoop ;And go round again SUB R1,R0,#1 ;Point at nonspace char ADR R0,cd__cliDef ;Point to the command defn MOV R2,R12 ;Point to my output buffer MOV R3,#256 ;And get its size SWI OS_ReadArgs ;Read the arguments nicely ; --- Check for help --- LDR R14,[R12,#8] ;Load the help flag CMP R14,#0 ;Is it set? BNE cd__help ;Yes -- then give help ; --- Now find the variable name --- LDR R4,[R12,#0] ;Load the name value CMP R4,#0 ;Is it set? ADREQ R4,cd__defaultName ;No -- point to a default ; --- Do the right thing --- LDR R14,[R12,#12] ;Load the `remove' flag CMP R14,#0 ;Is it set? BNE cd__remove ;Yes -- remove the variable ; --- Load the maximum length of the string --- LDR R1,[R12,#4] ;Load the length value CMP R1,#0 ;Is it zero? MOVEQ R2,#-1 ;Yes -- have a very big max BEQ cd__gotLength ;And skip onwards MOV R0,#10+(1<<31) ;Default is base 10 SWI OS_ReadUnsigned ;Read the value nicely CMP R2,#20 ;Is the length OK? BLO cd__badLength ;No -- that's an error cd__gotLength STR R2,cd__maxLen ;Store the length in code ; --- Set the variable value --- MOV R0,R4 ;Point to the variable name ADR R14,cd__varBase ;Point to the variable base LDMIA R14,{R1,R2} ;Load the base and length MOV R3,#0 ;No context value MOV R4,#16 ;This is a code variable SWI OS_SetVarVal ;Install the variable nicely SWI OS_Exit ; --- Remove an installed variable --- cd__remove MOV R0,R4 ;Point to the variable name MOV R2,#-1 ;Remove the variable MOV R3,#0 ;No context value MOV R4,#16 ;Remove code variable SWI OS_SetVarVal ;Remove the variable SWI OS_Exit cd__cliDef DCB "var,maxlen=length,help/S,remove/S",0 cd__defaultName DCB "CSD",0 cd__badOSVer ADR R0,cd__ro3Only ;Point to the error message SWI OS_GenerateError ;Report the error cd__ro3Only DCD 1 DCB "currDir only works on RISC OS 3.00 or later",0 cd__badLength ADR R0,cd__minSize ;Point to the error message SWI OS_GenerateError ;Report the error cd__minSize DCD 1 DCB "Maximum length must be at least 20",0 cd__varBase DCD cd__variable DCD cd__varEnd-cd__variable+512 ; --- Return help on the program --- cd__help ADR R0,cd__helpText ;Point to the help text MOV R1,#0 ;Use the default dictionary ADR R2,version ;Point to the version string SWI OS_PrettyPrint ;Print the string SWI OS_Exit cd__helpText DCB 27,0,13 DCB 13 DCB "Syntax: currDir [-var ] " DCB "[-maxlen ] [-remove]",13 DCB 13 DCB "Sets a variable (by default the variable 'CSD', " DCB "although you can change this) to contain the name " DCB "of the currently selected directory.",13 DCB 13 DCB "Optionally, you can set a maximum length. If you " DCB "do, the directory name will be shortened to only " DCB "display the name of the filing system, disk name " DCB "(if present), and the tail end of the path.",13 DCB 0 ;----- The code variable ---------------------------------------------------- cd__variable ROUT B cd__cantWrite ;Handle attempt to write ; --- Perform the read operation --- STMFD R13!,{R3-R5,R12,R14} ;Save some registers ADR R12,cd__buffer ;Set up the buffer pointer MOV R0,#37 ;Canonicalise path ADR R1,cd__atSign ;Point to the `@' magic char MOV R2,R12 ;Point at the buffer MOV R3,#0 ;No path variable MOV R4,#0 ;No path variable still MOV R5,#512 ;The size of my buffer SWI XOS_FSControl ;Read the canonical path ADRVS R2,cd__unset ;If not point at default ; --- Count the length --- MOV R0,R12 ;Point at the buffer MOV R1,R12 ;Start truncate at beginning MOV R2,#0 ;Current length MOV R3,#0 ;Current state 00cd__variable LDRB R14,[R0],#1 ;Load the next byte CMP R14,#32 ;Is this the string end? BLO %10cd__variable ;Yes -- skip to the end ADD R2,R2,#1 ;Bump the length counter CMP R14,#':' ;Is it a colon? BEQ %02cd__variable ;Yes -- handle it then CMP R14,#'%' ;Is it a library? CMPNE R14,#'$' ;Or a root spec? CMPNE R14,#'&' ;Or a URD spec? MOVEQ R1,R0 ;Yes -- truncate here CMP R14,#'.' ;Is it a dot? BNE %00cd__variable ;No -- go round again ; --- We found a dot --- CMP R3,#2 ;Did we find two colons? SUBEQ R1,R0,#1 ;Yes -- truncate here MOVEQ R3,#3 ;And don't do it again B %00cd__variable ;Go round again ; --- Found a colon -- check it out --- 02cd__variable CMP R3,#0 ;How many colons matched? MOVEQ R1,R0 ;None yet -- truncate here CMPNE R3,#1 ;Or maybe we've had one ADDEQ R3,R3,#1 ;Bump the counter B %00cd__variable ;Go round again ; --- Check the length now --- 10cd__variable LDR R5,cd__maxLen ;Load the maximum length SUBS R4,R2,R5 ;Are we OK here? BLS %30cd__variable ;Yes -- skip onwards then ; --- Truncate the string --- ; ; R4 is how many bytes we have to lose. ADD R0,R1,R4 ;Point to where we copy from MOV R2,#3 ;Countdown for ellipsis 20cd__variable LDRB R14,[R0],#1 ;Load the byte out CMP R14,#32 ;Is this the end of it all? BLO %25cd__variable ;Yes -- skip to end then SUBS R2,R2,#1 ;No -- decrement countdown MOVGE R14,#'.' ;Substitute a dot if needed STRB R14,[R1],#1 ;Store the byte in buffer B %20cd__variable ;No -- go round again then 25cd__variable STRB R14,[R1],#1 ;Store the byte in buffer MOV R2,R5 ;Length is in R2 on exit ; --- Return the variable --- 30cd__variable MOV R0,R12 ;Point to the string LDMFD R13!,{R3-R5,R12,PC}^ ;Return to caller cd__maxLen DCD 0 cd__atSign DCB "@",0 cd__unset DCB "",0 ; --- Make an error about writing to the variable --- cd__cantWrite ADR R0,cd__writeMsg ;Point to error ORRS PC,R14,#V_flag ;And return it cd__writeMsg DCD 1 DCB "Can't write current directory variables",0 ALIGN cd__buffer cd__varEnd ;----- That's all, folks ---------------------------------------------------- END