mirror of
https://github.com/GnoConsortium/gno.git
synced 2024-11-18 19:09:31 +00:00
6269a8ca25
Fixed several mutual exclusion problems, including a particularly nasty one that would cause gsh to loop forever inside the memory manager. (You could identify this one by the "BRA (-23)" at the bottom of the infinite loop.) Fixed the string vector print routine to properly handle all numbers of entries in the hash table. Previously, it would always print duplicate entries if there were < 6 commands hashed, and would sometimes print duplicates (depending on previous contents of an internal table) for other numbers of commands. gsh would wait on background processes started from an exec file (executed, not sourced). Now the exec file does not wait on the process, but the background process is not associated with the parent shell after the exec file terminates. Made gsh globbing work more like csh: if none of the requested patterns are found, print "No match" and exit. At startup, if /etc/glogin, $HOME/glogin, or $HOME/gshrc does not exist, don't report a "file not found" error message. (PR#100)
859 lines
12 KiB
NASM
859 lines
12 KiB
NASM
**************************************************************************
|
|
*
|
|
* The GNO Shell Project
|
|
*
|
|
* Developed by:
|
|
* Jawaid Bazyar
|
|
* Tim Meekins
|
|
*
|
|
* $Id: alias.asm,v 1.8 1998/12/31 18:29:11 tribby Exp $
|
|
*
|
|
**************************************************************************
|
|
*
|
|
* ALIAS.ASM
|
|
* By Tim Meekins
|
|
* Modified by Dave Tribby for GNO 2.0.6
|
|
*
|
|
* Note: text set up for tabs at col 16, 22, 41, 49, 57, 65
|
|
* | | | | | |
|
|
* ^ ^ ^ ^ ^ ^
|
|
**************************************************************************
|
|
*
|
|
* Interfaces defined in this file:
|
|
*
|
|
* alias subroutine (4:argv,2:argc)
|
|
* Returns with status=0 in Accumulator
|
|
*
|
|
* unalias subroutine (4:argv,2:argc)
|
|
* return 2:status
|
|
*
|
|
* initalias jsr/rts with no parameters
|
|
*
|
|
* expandalias subroutine (4:cmd)
|
|
* return 4:buf
|
|
*
|
|
* addalias subroutine (4:aliasname,4:aliasval)
|
|
* return
|
|
*
|
|
* removealias subroutine (4:aliasname)
|
|
* return
|
|
*
|
|
* findalias subroutine (4:aliasname),space
|
|
* return 4:value
|
|
*
|
|
* startalias jsl/rtl with no parameters
|
|
*
|
|
* nextalias subroutine (4:p)
|
|
* return 2:hashvalz
|
|
*
|
|
*
|
|
**************************************************************************
|
|
|
|
mcopy /obj/gno/bin/gsh/alias.mac
|
|
|
|
dummyalias start ; ends up in root
|
|
end
|
|
|
|
setcom 60
|
|
|
|
VTABSIZE gequ 17
|
|
|
|
**************************************************************************
|
|
*
|
|
* ALIAS: builtin command
|
|
* syntax: alias [name [def]]
|
|
*
|
|
* set aliases
|
|
*
|
|
**************************************************************************
|
|
|
|
alias START
|
|
|
|
using AliasData
|
|
|
|
arg equ 1
|
|
space equ arg+4
|
|
argc equ space+3
|
|
argv equ argc+2
|
|
end equ argv+4
|
|
|
|
; subroutine (4:argv,2:argc),space
|
|
|
|
tsc
|
|
sec
|
|
sbc #space-1
|
|
tcs
|
|
phd
|
|
tcd
|
|
|
|
lock AliasMutex
|
|
lda argc How many arguments were provided?
|
|
dec a
|
|
beq showall None -- show all alias names.
|
|
dec a
|
|
beq showone One -- show a single name.
|
|
jmp setalias More -- set an alias.
|
|
|
|
;
|
|
; Show all aliases
|
|
;
|
|
showall jsl startalias
|
|
showloop jsl nextalias
|
|
sta arg
|
|
stx arg+2
|
|
ora arg+2
|
|
beq noshow
|
|
ldy #6
|
|
lda [arg],y
|
|
tax
|
|
ldy #4
|
|
lda [arg],y
|
|
jsr puts
|
|
lda #':'
|
|
jsr putchar
|
|
lda #' '
|
|
jsr putchar
|
|
ldy #10
|
|
lda [arg],y
|
|
tax
|
|
ldy #8
|
|
lda [arg],y
|
|
jsr puts
|
|
jsr newline
|
|
bra showloop
|
|
|
|
noshow jmp exit
|
|
|
|
;
|
|
; Show a single alias
|
|
;
|
|
showone ldy #4+2
|
|
lda [argv],y
|
|
tax
|
|
pha ;for findalias
|
|
ldy #4
|
|
lda [argv],y
|
|
pha
|
|
jsr puts Print name.
|
|
lda #':' Print ": ".
|
|
jsr putchar
|
|
lda #' '
|
|
jsr putchar
|
|
jsl findalias
|
|
sta arg
|
|
stx arg+2
|
|
ora arg+2
|
|
beq notthere
|
|
lda arg
|
|
jsr puts Print alias value.
|
|
jsr newline Print newline.
|
|
jmp exit All done.
|
|
|
|
notthere ldx #^noalias Print message:
|
|
lda #noalias 'Alias not defined'
|
|
jsr puts
|
|
jmp exit
|
|
|
|
;
|
|
; Set an alias name
|
|
;
|
|
setalias ldy #4+2 ;put alias name on stack
|
|
lda [argv],y
|
|
pha
|
|
ldy #4
|
|
lda [argv],y
|
|
pha
|
|
|
|
ph4 #2
|
|
~NEW
|
|
sta arg
|
|
stx arg+2
|
|
lda #0
|
|
sta [arg]
|
|
|
|
add2 argv,#8,argv
|
|
|
|
dec2 argc
|
|
|
|
buildalias lda argc
|
|
beq setit
|
|
|
|
pei (arg+2)
|
|
pei (arg)
|
|
pei (arg+2)
|
|
pei (arg)
|
|
ldy #2
|
|
lda [argv],y
|
|
pha
|
|
lda [argv]
|
|
pha
|
|
jsr catcstr
|
|
stx arg+2
|
|
sta arg
|
|
jsl nullfree
|
|
|
|
pei (arg+2)
|
|
pei (arg)
|
|
pei (arg+2)
|
|
pei (arg)
|
|
ph4 #spacestr
|
|
jsr catcstr
|
|
stx arg+2
|
|
sta arg
|
|
jsl nullfree
|
|
|
|
dec argc
|
|
add2 argv,#4,argv
|
|
bra buildalias
|
|
|
|
setit pei (arg+2)
|
|
pei (arg)
|
|
jsl addalias
|
|
pei (arg+2)
|
|
pei (arg)
|
|
jsl nullfree
|
|
|
|
exit unlock AliasMutex
|
|
lda space
|
|
sta end-3
|
|
lda space+1
|
|
sta end-2
|
|
pld
|
|
tsc
|
|
clc
|
|
adc #end-4
|
|
tcs
|
|
|
|
lda #0 Return status always 0.
|
|
|
|
rtl
|
|
|
|
noalias dc c'Alias not defined',h'0d00'
|
|
spacestr dc c' ',h'00'
|
|
|
|
END
|
|
|
|
**************************************************************************
|
|
*
|
|
* UNALIAS: builtin command
|
|
* syntax: unalias [var ...]
|
|
*
|
|
* removes each alias listed
|
|
*
|
|
**************************************************************************
|
|
|
|
unalias START
|
|
|
|
using AliasData
|
|
|
|
status equ 0
|
|
space equ status+2
|
|
|
|
subroutine (4:argv,2:argc),space
|
|
|
|
lock AliasMutex
|
|
|
|
stz status
|
|
|
|
lda argc
|
|
dec a
|
|
bne loop
|
|
|
|
ldx #^Usage
|
|
lda #USage
|
|
jsr errputs
|
|
inc status Return status = 1.
|
|
bra done
|
|
|
|
loop add2 argv,#4,argv
|
|
dec argc
|
|
beq done
|
|
|
|
ldy #2
|
|
lda [argv],y
|
|
pha
|
|
lda [argv]
|
|
pha
|
|
jsl removealias
|
|
|
|
bra loop
|
|
|
|
done unlock AliasMutex
|
|
return 2:status
|
|
|
|
Usage dc c'Usage: unalias name ...',h'0d00'
|
|
|
|
END
|
|
|
|
;=========================================================================
|
|
;
|
|
; Init alias table
|
|
;
|
|
;=========================================================================
|
|
|
|
initalias START
|
|
|
|
using AliasData
|
|
|
|
; Set all entries in AliasTable to 0
|
|
|
|
lda #0
|
|
ldy #VTABSIZE
|
|
tax
|
|
yahaha sta AliasTable,x
|
|
inx2
|
|
sta AliasTable,x
|
|
inx2
|
|
dey
|
|
bne yahaha
|
|
|
|
rts
|
|
|
|
END
|
|
|
|
;=========================================================================
|
|
;
|
|
; Expand alias
|
|
;
|
|
;=========================================================================
|
|
|
|
expandalias START
|
|
|
|
outbuf equ 0
|
|
sub equ outbuf+4
|
|
word equ sub+4
|
|
buf equ word+4
|
|
space equ buf+4
|
|
|
|
subroutine (4:cmd),space
|
|
|
|
ph4 #1024
|
|
~NEW
|
|
stx buf+2
|
|
sta buf
|
|
stx outbuf+2
|
|
sta outbuf
|
|
jsl alloc1024
|
|
stx word+2
|
|
sta word
|
|
lda #0
|
|
sta [buf] In case we're called with empty string
|
|
sta [word]
|
|
;
|
|
; eat leading spaces
|
|
;
|
|
eatleader lda [cmd]
|
|
and #$FF
|
|
jeq done
|
|
cmp #' '
|
|
bne getword
|
|
inc cmd
|
|
sta [outbuf]
|
|
inc outbuf
|
|
bra eatleader
|
|
;
|
|
; find the leading word
|
|
;
|
|
getword short a
|
|
ldy #0
|
|
makeword lda [cmd],y
|
|
if2 @a,eq,#0,gotword
|
|
if2 @a,eq,#' ',gotword
|
|
if2 @a,eq,#';',gotword
|
|
if2 @a,eq,#'&',gotword
|
|
if2 @a,eq,#'|',gotword
|
|
if2 @a,eq,#'>',gotword
|
|
if2 @a,eq,#'<',gotword
|
|
if2 @a,eq,#13,gotword
|
|
if2 @a,eq,#9,gotword
|
|
if2 @a,eq,#10,gotword
|
|
sta [word],y
|
|
iny
|
|
bra makeword
|
|
;
|
|
; we got a word, now check if it's an alias
|
|
;
|
|
gotword lda #0
|
|
sta [word],y
|
|
long a
|
|
add2 @y,cmd,cmd
|
|
phy
|
|
pei (word+2)
|
|
pei (word)
|
|
jsl findalias
|
|
sta sub
|
|
stx sub+2
|
|
ora sub+2
|
|
beq noalias
|
|
;
|
|
; expand it, if you hadn't figured it out for yourself by now.
|
|
;
|
|
pla
|
|
ldy #0
|
|
putalias lda [sub],y
|
|
and #$FF
|
|
beq next
|
|
sta [outbuf]
|
|
inc outbuf
|
|
iny
|
|
bra putalias
|
|
;
|
|
; no alias, so just copy the original string
|
|
;
|
|
noalias plx
|
|
beq next
|
|
ldy #0
|
|
noalias2 lda [word],y
|
|
sta [outbuf]
|
|
inc outbuf
|
|
iny
|
|
dex
|
|
bne noalias2
|
|
;
|
|
; the alias is expanded, now copy until we reach the next command
|
|
;
|
|
next lda [cmd]
|
|
inc cmd
|
|
sta [outbuf]
|
|
inc outbuf
|
|
and #$FF
|
|
beq done
|
|
if2 @a,eq,#13,nextalias
|
|
if2 @a,eq,#';',nextalias
|
|
if2 @a,eq,#'&',nextalias
|
|
if2 @a,eq,#'|',nextalias
|
|
if2 @a,eq,#'\',backstabber
|
|
if2 @a,eq,#"'",singquoter
|
|
if2 @a,eq,#'"',doubquoter
|
|
bra next
|
|
;
|
|
; "\" found
|
|
;
|
|
backstabber lda [cmd]
|
|
inc cmd
|
|
sta [outbuf]
|
|
inc outbuf
|
|
and #$FF
|
|
beq done
|
|
bra next
|
|
;
|
|
; "'" found
|
|
;
|
|
singquoter lda [cmd]
|
|
inc cmd
|
|
sta [outbuf]
|
|
inc outbuf
|
|
and #$FF
|
|
beq done
|
|
if2 @a,ne,#"'",singquoter
|
|
bra next
|
|
;
|
|
; '"' found
|
|
;
|
|
doubquoter lda [cmd]
|
|
inc cmd
|
|
sta [outbuf]
|
|
inc outbuf
|
|
and #$FF
|
|
beq done
|
|
if2 @a,ne,#'"',doubquoter
|
|
bra next
|
|
|
|
;
|
|
; ";", "|", or "&" found: it's another command
|
|
;
|
|
nextalias jmp eatleader
|
|
|
|
done ldx word+2
|
|
lda word
|
|
jsl free1024
|
|
|
|
return 4:buf
|
|
|
|
END
|
|
|
|
;=========================================================================
|
|
;
|
|
; Add alias to table
|
|
;
|
|
;=========================================================================
|
|
|
|
addalias START
|
|
|
|
using AliasData
|
|
|
|
tmp equ 0
|
|
ptr equ tmp+4
|
|
hashval equ ptr+4
|
|
space equ hashval+4
|
|
|
|
subroutine (4:aliasname,4:aliasval),space
|
|
|
|
pei (aliasname+2)
|
|
pei (aliasname)
|
|
jsl hashalias
|
|
sta hashval
|
|
|
|
tax
|
|
lda AliasTable,x
|
|
sta ptr
|
|
lda AliasTable+2,x
|
|
sta ptr+2
|
|
|
|
search lda ptr
|
|
ora ptr+2
|
|
beq notfound
|
|
ldy #4
|
|
lda [ptr],y
|
|
tax
|
|
ldy #4+2
|
|
lda [ptr],y
|
|
pha
|
|
phx
|
|
pei (aliasname+2)
|
|
pei (aliasname)
|
|
jsr cmpcstr
|
|
jeq replace
|
|
ldy #2
|
|
lda [ptr]
|
|
tax
|
|
lda [ptr],y
|
|
sta ptr+2
|
|
stx ptr
|
|
bra search
|
|
|
|
replace ldy #8+2
|
|
lda [ptr],y
|
|
pha
|
|
ldy #8
|
|
lda [ptr],y
|
|
pha
|
|
jsl nullfree
|
|
pei (aliasval+2)
|
|
pei (aliasval)
|
|
jsr cstrlen
|
|
inc a
|
|
pea 0
|
|
pha
|
|
~NEW
|
|
sta tmp
|
|
stx tmp+2
|
|
ldy #8
|
|
sta [ptr],y
|
|
ldy #8+2
|
|
txa
|
|
sta [ptr],y
|
|
pei (aliasval+2)
|
|
pei (aliasval)
|
|
pei (tmp+2)
|
|
pei (tmp)
|
|
jsr copycstr
|
|
jmp done
|
|
|
|
notfound ph4 #4*3
|
|
~NEW
|
|
sta ptr
|
|
stx ptr+2
|
|
ldy #2
|
|
ldx hashval
|
|
lda AliasTable,x
|
|
sta [ptr]
|
|
lda AliasTable+2,x
|
|
sta [ptr],y
|
|
pei (aliasname+2)
|
|
pei (aliasname)
|
|
jsr cstrlen
|
|
inc a
|
|
pea 0
|
|
pha
|
|
~NEW
|
|
sta tmp
|
|
stx tmp+2
|
|
ldy #4
|
|
sta [ptr],y
|
|
ldy #4+2
|
|
txa
|
|
sta [ptr],y
|
|
pei (aliasname+2)
|
|
pei (aliasname)
|
|
pei (tmp+2)
|
|
pei (tmp)
|
|
jsr copycstr
|
|
pei (aliasval+2)
|
|
pei (aliasval)
|
|
jsr cstrlen
|
|
inc a
|
|
pea 0
|
|
pha
|
|
~NEW
|
|
sta tmp
|
|
stx tmp+2
|
|
ldy #8
|
|
sta [ptr],y
|
|
ldy #8+2
|
|
txa
|
|
sta [ptr],y
|
|
pei (aliasval+2)
|
|
pei (aliasval)
|
|
pei (tmp+2)
|
|
pei (tmp)
|
|
jsr copycstr
|
|
ldx hashval
|
|
lda ptr
|
|
sta AliasTable,x
|
|
lda ptr+2
|
|
sta AliasTable+2,x
|
|
|
|
done return
|
|
|
|
END
|
|
|
|
;=========================================================================
|
|
;
|
|
; Remove an alias
|
|
;
|
|
;=========================================================================
|
|
|
|
removealias START
|
|
|
|
using AliasData
|
|
|
|
oldptr equ 0
|
|
ptr equ oldptr+4
|
|
space equ ptr+4
|
|
|
|
subroutine (4:aliasname),space
|
|
|
|
pei (aliasname+2)
|
|
pei (aliasname)
|
|
jsl hashalias
|
|
tax
|
|
lda AliasTable,x
|
|
sta ptr
|
|
lda AliasTable+2,x
|
|
sta ptr+2
|
|
lda #^Aliastable
|
|
sta oldptr+2
|
|
clc
|
|
txa
|
|
adc #AliasTable
|
|
sta oldptr
|
|
|
|
searchloop ora2 ptr,ptr+2,@a
|
|
beq done
|
|
|
|
ldy #4+2
|
|
lda [ptr],y
|
|
pha
|
|
ldy #4
|
|
lda [ptr],y
|
|
pha
|
|
pei (aliasname+2)
|
|
pei (aliasname)
|
|
jsr cmpcstr
|
|
beq foundit
|
|
mv4 ptr,oldptr
|
|
ldy #2
|
|
lda [ptr],y
|
|
tax
|
|
lda [ptr]
|
|
sta ptr
|
|
stx ptr+2
|
|
bra searchloop
|
|
|
|
foundit ldy #2
|
|
lda [ptr],y
|
|
sta [oldptr],y
|
|
lda [ptr]
|
|
sta [oldptr]
|
|
ldy #4+2
|
|
lda [ptr],y
|
|
pha
|
|
ldy #4
|
|
lda [ptr],y
|
|
pha
|
|
jsl nullfree
|
|
ldy #8+2
|
|
lda [ptr],y
|
|
pha
|
|
ldy #8
|
|
lda [ptr],y
|
|
pha
|
|
jsl nullfree
|
|
pei (ptr+2)
|
|
pei (ptr)
|
|
jsl nullfree
|
|
|
|
done return
|
|
|
|
END
|
|
|
|
;=========================================================================
|
|
;
|
|
; Find an alias
|
|
;
|
|
;=========================================================================
|
|
|
|
findalias START
|
|
|
|
using AliasData
|
|
|
|
ptr equ 0
|
|
value equ ptr+4
|
|
space equ value+4
|
|
|
|
subroutine (4:aliasname),space
|
|
|
|
stz value
|
|
stz value+2
|
|
|
|
pei (aliasname+2)
|
|
pei (aliasname)
|
|
jsl hashalias
|
|
tax
|
|
lda AliasTable,x
|
|
sta ptr
|
|
lda AliasTable+2,x
|
|
sta ptr+2
|
|
|
|
searchloop ora2 ptr,ptr+2,@a
|
|
beq done
|
|
|
|
ldy #4+2
|
|
lda [ptr],y
|
|
pha
|
|
ldy #4
|
|
lda [ptr],y
|
|
pha
|
|
pei (aliasname+2)
|
|
pei (aliasname)
|
|
jsr cmpcstr
|
|
beq foundit
|
|
ldy #2
|
|
lda [ptr],y
|
|
tax
|
|
lda [ptr]
|
|
sta ptr
|
|
stx ptr+2
|
|
bra searchloop
|
|
|
|
foundit ldy #8
|
|
lda [ptr],y
|
|
sta value
|
|
ldy #8+2
|
|
lda [ptr],y
|
|
sta value+2
|
|
|
|
done return 4:value
|
|
|
|
END
|
|
|
|
;=========================================================================
|
|
;
|
|
; Start alias
|
|
;
|
|
;=========================================================================
|
|
|
|
startalias START
|
|
|
|
using AliasData
|
|
|
|
stz AliasNum
|
|
mv4 AliasTable,AliasPtr
|
|
rtl
|
|
|
|
END
|
|
|
|
;=========================================================================
|
|
;
|
|
; Next alias
|
|
;
|
|
;=========================================================================
|
|
|
|
nextalias START
|
|
|
|
using AliasData
|
|
|
|
value equ 0
|
|
space equ value+4
|
|
|
|
subroutine (0:fubar),space
|
|
|
|
stz value
|
|
stz value+2
|
|
puke if2 AliasNum,cs,#VTABSIZE,done
|
|
|
|
ora2 AliasPtr,AliasPtr+2,@a
|
|
bne flush
|
|
inc AliasNum
|
|
lda AliasNum
|
|
asl2 a
|
|
tax
|
|
lda AliasTable,x
|
|
sta AliasPtr
|
|
lda AliasTable+2,x
|
|
sta AliasPtr+2
|
|
bra puke
|
|
|
|
flush mv4 AliasPtr,value
|
|
ldy #2
|
|
lda [value]
|
|
sta AliasPtr
|
|
lda [value],y
|
|
sta AliasPtr+2
|
|
|
|
done return 4:value
|
|
|
|
END
|
|
|
|
;=========================================================================
|
|
;
|
|
; Hash an alias
|
|
;
|
|
;=========================================================================
|
|
|
|
hashalias PRIVATE
|
|
|
|
hashval equ 0
|
|
space equ hashval+2
|
|
|
|
subroutine (4:p),space
|
|
|
|
lda #11
|
|
sta hashval
|
|
|
|
ldy #0
|
|
loop asl hashval
|
|
lda [p],y
|
|
and #$FF
|
|
beq done
|
|
clc
|
|
adc hashval
|
|
sta hashval
|
|
iny
|
|
bra loop
|
|
done UDivide (hashval,#VTABSIZE),(@a,@a)
|
|
|
|
asl2 a ;Make it an index.
|
|
sta hashval
|
|
|
|
return 2:hashval
|
|
|
|
END
|
|
|
|
;=========================================================================
|
|
;
|
|
; Alias data
|
|
;
|
|
;=========================================================================
|
|
|
|
AliasData DATA
|
|
|
|
AliasNum dc i2'0'
|
|
AliasPtr dc i4'0'
|
|
AliasMutex key
|
|
|
|
AliasTable ds VTABSIZE*4
|
|
|
|
END
|