; ; pathUtil.s ; ; Messing about with path variables ; ; © 1994-1998 Straylight ; ;----- Licensing note ------------------------------------------------------- ; ; This file is part of Straylight's core utilities (coreutils). ; ; Coreutils 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. ; ; Coreutils 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 Coreutils. 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 ;----- Main code ------------------------------------------------------------ AREA |Asm$$Code|,CODE,READONLY ; --- path_addDir --- ; ; On entry: R0 == pointer to path variable name ; R1 == pointer to a directory string to add in ; R2 == flags: ; bits 0-7 == variable type (2 == literal, 4 == macro) ; bit 8 == create variable if doesn't exist ; ; On exit: CS if path element added, CC otherwise ; May return an error ; ; Use: Adds a directory to the given path variable. EXPORT path_addDir path_addDir ROUT BIC R14,R14,#V_flag+C_flag ;Assume everything is great STMFD R13!,{R0-R4,R14} ;Save a load of registers MOV R4,R0 ;Look after the variable name ; --- Read the font path variable --- ; ; We must make sure we don't expand it when we do. BL path__readPath ;Read the path variable BVS %90path_addDir ;If it failed, return error MOV R0,R1 ;Point to string to find BL path__findDir ;Try to find the directory LDMCSFD R13!,{R0-R4,PC}^ ;If it's in there, return ; --- Add in the directory then --- MOV R1,R11 ;Point to the string start LDRB R14,[R1,#0] ;Load the first byte CMP R14,#0 ;Is this a null string? BEQ %20path_addDir ;Yes -- omit the comma then ; --- Find the string end --- 10path_addDir LDRB R14,[R1,#1]! ;Load a new character out CMP R14,#0 ;Is this the end yet? BNE %10path_addDir ;No -- loop round again MOV R14,#',' ;Store a comma over the end STRB R14,[R1],#1 ;Store it at the end ; --- Copy the new directory string on the end --- 20path_addDir LDRB R14,[R0],#1 ;Load a source string byte CMP R14,#32 ;Is this the string end? STRCSB R14,[R1],#1 ;Store it in the buffer BCS %20path_addDir ;And look back round again ; --- Now set the variable value and return --- AND R2,R2,#&FF ;Get the variable type CMP R2,#4 ;Are we setting a lit string? MOVNE R14,#0 ;No -- null terminate then STRNEB R14,[R1],#1 ;Stick it on the end MOV R0,R4 ;Point to path variable name MOV R4,R2 ;Get variable type SUB R2,R1,R11 ;Get the string length out MOV R1,R11 ;Point to the new path string MOV R3,#0 ;No initial context here SWI XOS_SetVarVal ;Set the variable value BVS %90path_addDir ;Return an error if any LDMFD R13!,{R0-R4,R14} ;Return to caller if OK ORRS PC,R14,#C_flag ; --- Deal with any errors created --- 90path_addDir ADD R13,R13,#4 ;Don't return stacked R0 LDMFD R13!,{R1-R4,R14} ;Restore caller's registers ORRS PC,R14,#V_flag ;Return the error LTORG ; --- path__readPath --- ; ; On entry: R0 == pointer to path variable name ; R2 == flags passed to addDir/removeDir ; ; On exit: May return an error ; ; Use: Reads the value of the path variable into the buffer ; pointed to by R11. path__readPath ROUT BIC R14,R14,#V_flag ;Clear the error indicator STMFD R13!,{R0-R4,R14} ;Save a load of registers MOV R1,R11 ;Point to the scratch pad MOV R2,#256 ;Say the buffer is 256 bytes MOV R3,#0 ;No context space required MOV R4,#0 ;Don't expand the string SWI XOS_ReadVarVal ;Read the variable value BVS %90path__readPath ;If it failed, handle error MOV R14,#0 ;Store a zero byte on the end STRB R14,[R1,R2] ;Terminate the path string LDMFD R13!,{R0-R4,PC}^ ;Return to caller now 90 LDR R14,[R13,#8] ;Load the flags from stack TST R14,#&100 ;Is the `create' flag on? MOVNE R14,#0 ;Yes -- get a zero byte STRNEB R14,[R11,#0] ;Store in buffer LDMNEFD R13!,{R0-R4,PC}^ ;And return to caller ADD R13,R13,#4 ;Don't restore R0 on exit LDMFD R13!,{R1-R4,R14} ;Restore all the others ORRS PC,R14,#V_flag ;Return the error to caller LTORG ; --- path__findDir --- ; ; On entry: R0 == pointer to string to search for ; ; On exit: CS and R0 == pointer into path string if successful or ; CC and R0 preserved ; ; Use: Tries to find a named directory within a font path string. path__findDir ROUT STMFD R13!,{R1-R5,R14} ;Save a load of registers MOV R1,R11 ;Point to the path string MOV R3,R1 ;Keep a pointer to this dir ; --- Go through both strings --- 00path__findDir MOV R2,R0 ;Point to search pattern 01path__findDir LDRB R4,[R1],#1 ;Load a char from the path CMP R4,#32 ;Is it a space character? BEQ %01path__findDir ;Yes -- ignore it then 02path__findDir LDRB R5,[R2],#1 ;And one from the pattern CMP R5,#32 ;Is this the end of the dir? BCC %10path__findDir ;Yes -- deal with this CMP R4,#0 ;Is it the end of the path? BEQ %07path__findDir ;Yes -- deal with this CMP R4,R5 ;Do the characters match? LDREQB R4,[R1],#1 ;Yes -- load next path char BEQ %02path__findDir ;And go round again ; --- Found a mismatch --- ; ; We have to find the next path element 05path__findDir CMP R4,#',' ;Is it a comma? SUBEQ R3,R1,#1 ;Yes -- point to it nicely BEQ %00path__findDir ;And go round again CMP R4,#0 ;Is it the string end? LDRNEB R4,[R1],#1 ;Load a char from the path BNE %05path__findDir ;No -- continue the search 07path__findDir LDMFD R13!,{R1-R5,R14} ;Restore the registers BICS PC,R14,#C_flag ;Return with carry clear ; --- We reached the end of the directory --- 10path__findDir CMP R4,#32 ;Is it a space? LDREQB R4,[R1],#1 ;Load a char from the path BEQ %10path__findDir ;Yes -- allow trailing space CMP R4,#',' ;Is it a comma? CMPNE R4,#0 ;Or the end of the whole lot? BNE %05path__findDir ;No -- find the next one MOV R0,R3 ;Point to the path entry strt LDMFD R13!,{R1-R5,R14} ;Restore the registers ORRS PC,R14,#C_flag ;And return a success LTORG ; --- path_removeDir --- ; ; On entry: R0 == pointer to name of path variable ; R1 == pointer to a directory to remove ; R2 == flags: ; bits 0-7 == variable type (2 == literal, 4 == macro) ; bit 8 == create variable if doesn't exist ; ; On exit: May return an error ; ; Use: Removes an element from a given path variable. EXPORT path_removeDir path_removeDir ROUT BIC R14,R14,#V_flag+C_flag ;Clear error indicator STMFD R13!,{R0-R4,R14} ;Save a load of registers MOV R4,R0 ;Look after variable name BL path__readPath ;Read the actual path string BVS %90path_removeDir ;If it failed, handle it MOV R0,R1 ;Point to path element BL path__findDir ;Find the particular entry LDMCCFD R13!,{R0-R4,PC}^ ;Not there -- return ; --- Now find the end of the entry --- ADD R1,R0,#1 ;Keep the start pointer 10 LDRB R14,[R1],#1 ;Load a byte from it CMP R14,#',' ;Is it the dir end? CMPNE R14,#0 ;Or the end of the whole lot? BNE %10path_removeDir ;No -- go round again then ; --- Now remove this item from the list --- CMP R14,#',' ;Is this character a comma? CMPEQ R0,R11 ;And is the dir at the start? STRNEB R14,[R0],#1 ;Neither -- store it here 20 CMP R14,#0 ;Is this the string end? BEQ %50path_removeDir ;Yes -- go and set the var LDRB R14,[R1],#1 ;Get a new char from the path STRB R14,[R0],#1 ;And store it nicely B %20path_removeDir ;And go round for more ; --- Right -- the string bashing's over --- 50 AND R1,R2,#&FF ;Get the variable type CMP R1,#4 ;Are we setting a lit string? SUBEQ R0,R0,#1 ;Yes -- don't include null SUB R2,R0,R11 ;Get the length in R2 nicely MOV R0,R4 ;Point to the variable name MOV R4,R1 ;Get the variable type MOV R1,R11 ;Point to the string start MOV R3,#0 ;Don't mess with wildcards SWI XOS_SetVarVal ;Set the variable value BVS %90path_removeDir ;If it failed, return error LDMFD R13!,{R0-R4,R14} ;Return to caller ORRS PC,R14,#C_flag ; --- Something went wrong --- 90 ADD R13,R13,#4 ;Don't restore R0 on exit LDMFD R13!,{R1-R4,R14} ;Restore all the others ORRS PC,R14,#V_flag ;And return the error LTORG ;----- That's all, folks ---------------------------------------------------- END