Initial revision
[ssr] / StraySrc / Utilities / s / pathUtil
1 ;
2 ; pathUtil.s
3 ;
4 ; Messing about with path variables
5 ;
6 ; © 1994-1998 Straylight
7 ;
8
9 ;----- Licensing note -------------------------------------------------------
10 ;
11 ; This file is part of Straylight's core utilities (coreutils).
12 ;
13 ; Coreutils is free software; you can redistribute it and/or modify
14 ; it under the terms of the GNU General Public License as published by
15 ; the Free Software Foundation; either version 2, or (at your option)
16 ; any later version.
17 ;
18 ; Coreutils is distributed in the hope that it will be useful,
19 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ; GNU General Public License for more details.
22 ;
23 ; You should have received a copy of the GNU General Public License
24 ; along with Coreutils. If not, write to the Free Software Foundation,
25 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
27 ;----- Standard header ------------------------------------------------------
28
29 GET libs:header
30 GET libs:swis
31
32 ;----- Main code ------------------------------------------------------------
33
34 AREA |Asm$$Code|,CODE,READONLY
35
36 ; --- path_addDir ---
37 ;
38 ; On entry: R0 == pointer to path variable name
39 ; R1 == pointer to a directory string to add in
40 ; R2 == flags:
41 ; bits 0-7 == variable type (2 == literal, 4 == macro)
42 ; bit 8 == create variable if doesn't exist
43 ;
44 ; On exit: CS if path element added, CC otherwise
45 ; May return an error
46 ;
47 ; Use: Adds a directory to the given path variable.
48
49 EXPORT path_addDir
50 path_addDir ROUT
51
52 BIC R14,R14,#V_flag+C_flag ;Assume everything is great
53 STMFD R13!,{R0-R4,R14} ;Save a load of registers
54 MOV R4,R0 ;Look after the variable name
55
56 ; --- Read the font path variable ---
57 ;
58 ; We must make sure we don't expand it when we do.
59
60 BL path__readPath ;Read the path variable
61 BVS %90path_addDir ;If it failed, return error
62 MOV R0,R1 ;Point to string to find
63 BL path__findDir ;Try to find the directory
64 LDMCSFD R13!,{R0-R4,PC}^ ;If it's in there, return
65
66 ; --- Add in the directory then ---
67
68 MOV R1,R11 ;Point to the string start
69 LDRB R14,[R1,#0] ;Load the first byte
70 CMP R14,#0 ;Is this a null string?
71 BEQ %20path_addDir ;Yes -- omit the comma then
72
73 ; --- Find the string end ---
74
75 10path_addDir LDRB R14,[R1,#1]! ;Load a new character out
76 CMP R14,#0 ;Is this the end yet?
77 BNE %10path_addDir ;No -- loop round again
78
79 MOV R14,#',' ;Store a comma over the end
80 STRB R14,[R1],#1 ;Store it at the end
81
82 ; --- Copy the new directory string on the end ---
83
84 20path_addDir LDRB R14,[R0],#1 ;Load a source string byte
85 CMP R14,#32 ;Is this the string end?
86 STRCSB R14,[R1],#1 ;Store it in the buffer
87 BCS %20path_addDir ;And look back round again
88
89 ; --- Now set the variable value and return ---
90
91 AND R2,R2,#&FF ;Get the variable type
92 CMP R2,#4 ;Are we setting a lit string?
93 MOVNE R14,#0 ;No -- null terminate then
94 STRNEB R14,[R1],#1 ;Stick it on the end
95 MOV R0,R4 ;Point to path variable name
96 MOV R4,R2 ;Get variable type
97 SUB R2,R1,R11 ;Get the string length out
98 MOV R1,R11 ;Point to the new path string
99 MOV R3,#0 ;No initial context here
100 SWI XOS_SetVarVal ;Set the variable value
101 BVS %90path_addDir ;Return an error if any
102
103 LDMFD R13!,{R0-R4,R14} ;Return to caller if OK
104 ORRS PC,R14,#C_flag
105
106 ; --- Deal with any errors created ---
107
108 90path_addDir ADD R13,R13,#4 ;Don't return stacked R0
109 LDMFD R13!,{R1-R4,R14} ;Restore caller's registers
110 ORRS PC,R14,#V_flag ;Return the error
111
112 LTORG
113
114 ; --- path__readPath ---
115 ;
116 ; On entry: R0 == pointer to path variable name
117 ; R2 == flags passed to addDir/removeDir
118 ;
119 ; On exit: May return an error
120 ;
121 ; Use: Reads the value of the path variable into the buffer
122 ; pointed to by R11.
123
124 path__readPath ROUT
125
126 BIC R14,R14,#V_flag ;Clear the error indicator
127 STMFD R13!,{R0-R4,R14} ;Save a load of registers
128 MOV R1,R11 ;Point to the scratch pad
129 MOV R2,#256 ;Say the buffer is 256 bytes
130 MOV R3,#0 ;No context space required
131 MOV R4,#0 ;Don't expand the string
132 SWI XOS_ReadVarVal ;Read the variable value
133 BVS %90path__readPath ;If it failed, handle error
134 MOV R14,#0 ;Store a zero byte on the end
135 STRB R14,[R1,R2] ;Terminate the path string
136 LDMFD R13!,{R0-R4,PC}^ ;Return to caller now
137
138 90 LDR R14,[R13,#8] ;Load the flags from stack
139 TST R14,#&100 ;Is the `create' flag on?
140 MOVNE R14,#0 ;Yes -- get a zero byte
141 STRNEB R14,[R11,#0] ;Store in buffer
142 LDMNEFD R13!,{R0-R4,PC}^ ;And return to caller
143
144 ADD R13,R13,#4 ;Don't restore R0 on exit
145 LDMFD R13!,{R1-R4,R14} ;Restore all the others
146 ORRS PC,R14,#V_flag ;Return the error to caller
147
148 LTORG
149
150 ; --- path__findDir ---
151 ;
152 ; On entry: R0 == pointer to string to search for
153 ;
154 ; On exit: CS and R0 == pointer into path string if successful or
155 ; CC and R0 preserved
156 ;
157 ; Use: Tries to find a named directory within a font path string.
158
159 path__findDir ROUT
160
161 STMFD R13!,{R1-R5,R14} ;Save a load of registers
162 MOV R1,R11 ;Point to the path string
163 MOV R3,R1 ;Keep a pointer to this dir
164
165 ; --- Go through both strings ---
166
167 00path__findDir MOV R2,R0 ;Point to search pattern
168 01path__findDir LDRB R4,[R1],#1 ;Load a char from the path
169 CMP R4,#32 ;Is it a space character?
170 BEQ %01path__findDir ;Yes -- ignore it then
171
172 02path__findDir LDRB R5,[R2],#1 ;And one from the pattern
173 CMP R5,#32 ;Is this the end of the dir?
174 BCC %10path__findDir ;Yes -- deal with this
175
176 CMP R4,#0 ;Is it the end of the path?
177 BEQ %07path__findDir ;Yes -- deal with this
178
179 CMP R4,R5 ;Do the characters match?
180 LDREQB R4,[R1],#1 ;Yes -- load next path char
181 BEQ %02path__findDir ;And go round again
182
183 ; --- Found a mismatch ---
184 ;
185 ; We have to find the next path element
186
187 05path__findDir CMP R4,#',' ;Is it a comma?
188 SUBEQ R3,R1,#1 ;Yes -- point to it nicely
189 BEQ %00path__findDir ;And go round again
190 CMP R4,#0 ;Is it the string end?
191 LDRNEB R4,[R1],#1 ;Load a char from the path
192 BNE %05path__findDir ;No -- continue the search
193 07path__findDir LDMFD R13!,{R1-R5,R14} ;Restore the registers
194 BICS PC,R14,#C_flag ;Return with carry clear
195
196 ; --- We reached the end of the directory ---
197
198 10path__findDir CMP R4,#32 ;Is it a space?
199 LDREQB R4,[R1],#1 ;Load a char from the path
200 BEQ %10path__findDir ;Yes -- allow trailing space
201 CMP R4,#',' ;Is it a comma?
202 CMPNE R4,#0 ;Or the end of the whole lot?
203 BNE %05path__findDir ;No -- find the next one
204 MOV R0,R3 ;Point to the path entry strt
205 LDMFD R13!,{R1-R5,R14} ;Restore the registers
206 ORRS PC,R14,#C_flag ;And return a success
207
208 LTORG
209
210 ; --- path_removeDir ---
211 ;
212 ; On entry: R0 == pointer to name of path variable
213 ; R1 == pointer to a directory to remove
214 ; R2 == flags:
215 ; bits 0-7 == variable type (2 == literal, 4 == macro)
216 ; bit 8 == create variable if doesn't exist
217 ;
218 ; On exit: May return an error
219 ;
220 ; Use: Removes an element from a given path variable.
221
222 EXPORT path_removeDir
223 path_removeDir ROUT
224
225 BIC R14,R14,#V_flag+C_flag ;Clear error indicator
226 STMFD R13!,{R0-R4,R14} ;Save a load of registers
227 MOV R4,R0 ;Look after variable name
228
229 BL path__readPath ;Read the actual path string
230 BVS %90path_removeDir ;If it failed, handle it
231 MOV R0,R1 ;Point to path element
232 BL path__findDir ;Find the particular entry
233 LDMCCFD R13!,{R0-R4,PC}^ ;Not there -- return
234
235 ; --- Now find the end of the entry ---
236
237 ADD R1,R0,#1 ;Keep the start pointer
238 10 LDRB R14,[R1],#1 ;Load a byte from it
239 CMP R14,#',' ;Is it the dir end?
240 CMPNE R14,#0 ;Or the end of the whole lot?
241 BNE %10path_removeDir ;No -- go round again then
242
243 ; --- Now remove this item from the list ---
244
245 CMP R14,#',' ;Is this character a comma?
246 CMPEQ R0,R11 ;And is the dir at the start?
247 STRNEB R14,[R0],#1 ;Neither -- store it here
248
249 20 CMP R14,#0 ;Is this the string end?
250 BEQ %50path_removeDir ;Yes -- go and set the var
251 LDRB R14,[R1],#1 ;Get a new char from the path
252 STRB R14,[R0],#1 ;And store it nicely
253 B %20path_removeDir ;And go round for more
254
255 ; --- Right -- the string bashing's over ---
256
257 50 AND R1,R2,#&FF ;Get the variable type
258 CMP R1,#4 ;Are we setting a lit string?
259 SUBEQ R0,R0,#1 ;Yes -- don't include null
260
261 SUB R2,R0,R11 ;Get the length in R2 nicely
262 MOV R0,R4 ;Point to the variable name
263 MOV R4,R1 ;Get the variable type
264 MOV R1,R11 ;Point to the string start
265 MOV R3,#0 ;Don't mess with wildcards
266 SWI XOS_SetVarVal ;Set the variable value
267 BVS %90path_removeDir ;If it failed, return error
268
269 LDMFD R13!,{R0-R4,R14} ;Return to caller
270 ORRS PC,R14,#C_flag
271
272 ; --- Something went wrong ---
273
274 90 ADD R13,R13,#4 ;Don't restore R0 on exit
275 LDMFD R13!,{R1-R4,R14} ;Restore all the others
276 ORRS PC,R14,#V_flag ;And return the error
277
278 LTORG
279
280 ;----- That's all, folks ----------------------------------------------------
281
282 END