chiark / gitweb /
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