Initial revision
[ssr] / StraySrc / MiscToys / CurrDir / s / currDir
1 ;
2 ; currDir.s
3 ;
4 ; Puts the current directory in a code variable
5 ;
6 ; © 1994-1998 Straylight
7 ;
8
9 ;----- Licensing note -------------------------------------------------------
10 ;
11 ; CurrDir is free software; you can redistribute it and/or modify
12 ; it under the terms of the GNU General Public License as published by
13 ; the Free Software Foundation; either version 2, or (at your option)
14 ; any later version.
15 ;
16 ; CurrDir is distributed in the hope that it will be useful,
17 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ; GNU General Public License for more details.
20 ;
21 ; You should have received a copy of the GNU General Public License
22 ; along with CurrDir. If not, write to the Free Software Foundation,
23 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
25 ;----- Standard header ------------------------------------------------------
26
27 GET libs:header
28 GET libs:swis
29
30 ;----- External dependencies ------------------------------------------------
31
32 IMPORT version
33 IMPORT |Image$$RW$$Limit|
34
35 ;----- Main code ------------------------------------------------------------
36
37 AREA |Asm$$Code|,CODE,READONLY
38 ENTRY
39
40 ; --- main ---
41 ;
42 ; On entry: --
43 ;
44 ; On exit: Via OS_Exit
45 ;
46 ; Use: Installs the CurrDir variable.
47
48 main ROUT
49
50 ; --- Check for RISC OS 3 ---
51
52 MOV R0,#129 ;Read OS version number
53 MOV R1,#0
54 MOV R2,#255
55 SWI OS_Byte
56 CMP R1,#&A3 ;Check for RISC OS 3
57 BLO cd__badOSVer ;Wrong -- make an error
58
59 ; --- Parse the command line arguments ---
60
61 ADRL R12,|Image$$RW$$Limit| ;Find the program end
62 SWI OS_GetEnv ;Read the command line
63 cd__skipLoop LDRB R14,[R0],#1 ;Get next byte from this
64 CMP R14,#32 ;Is it the end of the name?
65 BHI cd__skipLoop ;No -- go round again
66 cd__spaceLoop CMP R14,#32 ;Is this a space?
67 LDREQB R14,[R0],#1 ;Yes -- get another byte
68 BEQ cd__spaceLoop ;And go round again
69 SUB R1,R0,#1 ;Point at nonspace char
70 ADR R0,cd__cliDef ;Point to the command defn
71 MOV R2,R12 ;Point to my output buffer
72 MOV R3,#256 ;And get its size
73 SWI OS_ReadArgs ;Read the arguments nicely
74
75 ; --- Check for help ---
76
77 LDR R14,[R12,#8] ;Load the help flag
78 CMP R14,#0 ;Is it set?
79 BNE cd__help ;Yes -- then give help
80
81 ; --- Now find the variable name ---
82
83 LDR R4,[R12,#0] ;Load the name value
84 CMP R4,#0 ;Is it set?
85 ADREQ R4,cd__defaultName ;No -- point to a default
86
87 ; --- Do the right thing ---
88
89 LDR R14,[R12,#12] ;Load the `remove' flag
90 CMP R14,#0 ;Is it set?
91 BNE cd__remove ;Yes -- remove the variable
92
93 ; --- Load the maximum length of the string ---
94
95 LDR R1,[R12,#4] ;Load the length value
96 CMP R1,#0 ;Is it zero?
97 MOVEQ R2,#-1 ;Yes -- have a very big max
98 BEQ cd__gotLength ;And skip onwards
99 MOV R0,#10+(1<<31) ;Default is base 10
100 SWI OS_ReadUnsigned ;Read the value nicely
101 CMP R2,#20 ;Is the length OK?
102 BLO cd__badLength ;No -- that's an error
103 cd__gotLength STR R2,cd__maxLen ;Store the length in code
104
105 ; --- Set the variable value ---
106
107 MOV R0,R4 ;Point to the variable name
108 ADR R14,cd__varBase ;Point to the variable base
109 LDMIA R14,{R1,R2} ;Load the base and length
110 MOV R3,#0 ;No context value
111 MOV R4,#16 ;This is a code variable
112 SWI OS_SetVarVal ;Install the variable nicely
113 SWI OS_Exit
114
115 ; --- Remove an installed variable ---
116
117 cd__remove MOV R0,R4 ;Point to the variable name
118 MOV R2,#-1 ;Remove the variable
119 MOV R3,#0 ;No context value
120 MOV R4,#16 ;Remove code variable
121 SWI OS_SetVarVal ;Remove the variable
122 SWI OS_Exit
123
124 cd__cliDef DCB "var,maxlen=length,help/S,remove/S",0
125 cd__defaultName DCB "CSD",0
126
127 cd__badOSVer ADR R0,cd__ro3Only ;Point to the error message
128 SWI OS_GenerateError ;Report the error
129
130 cd__ro3Only DCD 1
131 DCB "currDir only works on RISC OS 3.00 or later",0
132
133 cd__badLength ADR R0,cd__minSize ;Point to the error message
134 SWI OS_GenerateError ;Report the error
135
136 cd__minSize DCD 1
137 DCB "Maximum length must be at least 20",0
138
139 cd__varBase DCD cd__variable
140 DCD cd__varEnd-cd__variable+512
141
142 ; --- Return help on the program ---
143
144 cd__help ADR R0,cd__helpText ;Point to the help text
145 MOV R1,#0 ;Use the default dictionary
146 ADR R2,version ;Point to the version string
147 SWI OS_PrettyPrint ;Print the string
148 SWI OS_Exit
149
150 cd__helpText DCB 27,0,13
151 DCB 13
152 DCB "Syntax: currDir [-var <variableName>] "
153 DCB "[-maxlen <length>] [-remove]",13
154 DCB 13
155 DCB "Sets a variable (by default the variable 'CSD', "
156 DCB "although you can change this) to contain the name "
157 DCB "of the currently selected directory.",13
158 DCB 13
159 DCB "Optionally, you can set a maximum length. If you "
160 DCB "do, the directory name will be shortened to only "
161 DCB "display the name of the filing system, disk name "
162 DCB "(if present), and the tail end of the path.",13
163 DCB 0
164
165 ;----- The code variable ----------------------------------------------------
166
167 cd__variable ROUT
168
169 B cd__cantWrite ;Handle attempt to write
170
171 ; --- Perform the read operation ---
172
173 STMFD R13!,{R3-R5,R12,R14} ;Save some registers
174 ADR R12,cd__buffer ;Set up the buffer pointer
175 MOV R0,#37 ;Canonicalise path
176 ADR R1,cd__atSign ;Point to the `@' magic char
177 MOV R2,R12 ;Point at the buffer
178 MOV R3,#0 ;No path variable
179 MOV R4,#0 ;No path variable still
180 MOV R5,#512 ;The size of my buffer
181 SWI XOS_FSControl ;Read the canonical path
182 ADRVS R2,cd__unset ;If not point at default
183
184 ; --- Count the length ---
185
186 MOV R0,R12 ;Point at the buffer
187 MOV R1,R12 ;Start truncate at beginning
188 MOV R2,#0 ;Current length
189 MOV R3,#0 ;Current state
190
191 00cd__variable LDRB R14,[R0],#1 ;Load the next byte
192 CMP R14,#32 ;Is this the string end?
193 BLO %10cd__variable ;Yes -- skip to the end
194 ADD R2,R2,#1 ;Bump the length counter
195 CMP R14,#':' ;Is it a colon?
196 BEQ %02cd__variable ;Yes -- handle it then
197 CMP R14,#'%' ;Is it a library?
198 CMPNE R14,#'$' ;Or a root spec?
199 CMPNE R14,#'&' ;Or a URD spec?
200 MOVEQ R1,R0 ;Yes -- truncate here
201 CMP R14,#'.' ;Is it a dot?
202 BNE %00cd__variable ;No -- go round again
203
204 ; --- We found a dot ---
205
206 CMP R3,#2 ;Did we find two colons?
207 SUBEQ R1,R0,#1 ;Yes -- truncate here
208 MOVEQ R3,#3 ;And don't do it again
209 B %00cd__variable ;Go round again
210
211 ; --- Found a colon -- check it out ---
212
213 02cd__variable CMP R3,#0 ;How many colons matched?
214 MOVEQ R1,R0 ;None yet -- truncate here
215 CMPNE R3,#1 ;Or maybe we've had one
216 ADDEQ R3,R3,#1 ;Bump the counter
217 B %00cd__variable ;Go round again
218
219 ; --- Check the length now ---
220
221 10cd__variable LDR R5,cd__maxLen ;Load the maximum length
222 SUBS R4,R2,R5 ;Are we OK here?
223 BLS %30cd__variable ;Yes -- skip onwards then
224
225 ; --- Truncate the string ---
226 ;
227 ; R4 is how many bytes we have to lose.
228
229 ADD R0,R1,R4 ;Point to where we copy from
230 MOV R2,#3 ;Countdown for ellipsis
231 20cd__variable LDRB R14,[R0],#1 ;Load the byte out
232 CMP R14,#32 ;Is this the end of it all?
233 BLO %25cd__variable ;Yes -- skip to end then
234 SUBS R2,R2,#1 ;No -- decrement countdown
235 MOVGE R14,#'.' ;Substitute a dot if needed
236 STRB R14,[R1],#1 ;Store the byte in buffer
237 B %20cd__variable ;No -- go round again then
238
239 25cd__variable STRB R14,[R1],#1 ;Store the byte in buffer
240 MOV R2,R5 ;Length is in R2 on exit
241
242 ; --- Return the variable ---
243
244 30cd__variable MOV R0,R12 ;Point to the string
245 LDMFD R13!,{R3-R5,R12,PC}^ ;Return to caller
246
247 cd__maxLen DCD 0
248 cd__atSign DCB "@",0
249 cd__unset DCB "<Unset>",0
250
251 ; --- Make an error about writing to the variable ---
252
253 cd__cantWrite ADR R0,cd__writeMsg ;Point to error
254 ORRS PC,R14,#V_flag ;And return it
255
256 cd__writeMsg DCD 1
257 DCB "Can't write current directory variables",0
258
259 ALIGN
260
261 cd__buffer
262
263 cd__varEnd
264
265 ;----- That's all, folks ----------------------------------------------------
266
267 END