gno/bin/gsh/prompt.asm
tribby 1dc5497309 Added startup protocol as requested by Devin Reed (PR#78) and Steve Reeves
(PR#85, PR#86):
   For login shells (command line starts with '-'),
	If $PATH doesn't start with ':' or contain a space,
	   change all ":" to " ".
	source /etc/glogin
	source $HOME/glogin
$HOME/gshrc is sourced afterward for both login and non-login shells.

Don't the print number of hashed commands (from "rehash") until all
initialization is completed.

Only pass exported environment variables to child processes, and prevent child
processes from changing parent's environment.

A null command followed by a redirection of stdout, for example
  > /tmp/list
would cause an error message "<garbage> not found" due to incorrect
setting of command buffer pointer.

Filename completion did not work following ">&" or ">" without a trailing
space.

Entabbed all the asm files, saving more than 36,000 bytes.
1998-09-08 16:53:14 +00:00

446 lines
7.5 KiB
NASM

*************************************************************************
*
* The GNO Shell Project
*
* Developed by:
* Jawaid Bazyar
* Tim Meekins
*
* $Id: prompt.asm,v 1.6 1998/09/08 16:53:12 tribby Exp $
*
**************************************************************************
*
* PROMPT.ASM
* By Tim Meekins
* Modified by Dave Tribby for GNO 2.0.6
*
* This displays the command-line prompt
*
* Note: text set up for tabs at col 16, 22, 41, 49, 57, 65
* | | | | | |
* ^ ^ ^ ^ ^ ^
**************************************************************************
mcopy /obj/gno/bin/gsh/prompt.mac
dummyprompt start ; ends up in .root
end
setcom 60
WritePrompt START
using HistoryData
prompt equ 0
promptgsbuf equ prompt+4
usergsbuf equ promptgsbuf+4
hour equ usergsbuf+4
minute equ hour+2
offset equ minute+2
pfx equ offset+2
space equ pfx+4
year equ hour
monday equ minute
precmd equ prompt
subroutine (0:dummy),space
ph4 #precmdstr If "precmd" alias is defined,
jsl findalias
sta precmd
stx precmd+2
ora precmd+2
beq getvar
pei (precmd+2) execute it before parsing prompt.
pei (precmd)
ph2 #0
jsl execute
;
; Get value of $PROMPT environment variable
;
getvar ph4 #promptname
jsl getenv
php Turn off interrupts: mutex
sei won't do what we want!
sta promptgsbuf Save pointer to GS/OS result buffer.
stx promptgsbuf+2 If there is no memory to hold it,
ora promptgsbuf+2 it's undefined, or it has a
bne parseprompt length of 0,
ldx #^dfltPrompt
lda #dfltPrompt
jsr puts print the default prompt
bra donemark2 and exit.
;
; Prompt string begins in result buffer after the two length words
;
parseprompt anop
clc
lda promptgsbuf
adc #4
sta prompt
lda promptgsbuf+2
adc #0
sta prompt+2
promptloop lda [prompt]
incad prompt
and #$FF
beq done
cmp #'%'
beq special
cmp #'!'
jeq phist
cmp #'\'
jeq quoteit
_putchar jsr putchar
bra promptloop
done jsr standend
jsr cursoron
donemark2 anop
plp Restore interrupts.
pei (promptgsbuf+2) Free $PROMPT value buffer
pei (promptgsbuf)
jsl nullfree
jsr flush
return
;
; Previous character was a "%". Handle special character flags
;
special lda [prompt] Get character following "%".
incad prompt
and #$FF
beq done If end of string, all done.
cmp #'%' If another "%",
beq _putchar print the "%"
cmp #'h' If 'h'
beq phist
cmp #'!' or '!',
beq phist print history number.
cmp #'t' If 't'
beq ptime
cmp #'@' or '@',
beq ptime print time (am/pm format)
cmp #'S' If 'S',
jeq pstandout turn inverse mode on.
cmp #'s' If 's',
jeq pstandend turn inverse mode off.
cmp #'U' If 'U',
jeq punderline turn underline mode on.
cmp #'u' If 'u',
jeq punderend turn underline mode off
cmp #'d' If 'd'
jeq pcwd
cmp #'/' or '/',
jeq pcwd print working directory.
cmp #'c' If 'c'
jeq pcwdend
cmp #'C' or 'C'
jeq pcwdend
cmp #'.' or '.',
jeq pcwdend print final part of wrk dir.
cmp #'n' If 'n',
jeq puser print $USER
cmp #'W' If 'W',
jeq pdate1 print date (mm/dd/yy)
cmp #'D' If 'D',
jeq pdate2 print date (yy-mm-dd)
cmp #'~' If '~',
jeq ptilde print wrk dir with ~ subs.
jmp promptloop If none of these characters, ignore it.
;
; Put history number
;
phist lda lasthist
inc a
jsr WriteNum
jmp promptloop
;
; Print current time
;
ptime ReadTimeHex (minute,hour,@a,@a)
lda hour
and #$FF
if2 @a,cc,#13,ptime2
sub2 @a,#12,@a
ptime2 if2 @a,ne,#0,ptime2b
lda #12
ptime2b jsr WriteNum
lda #':'
jsr putchar
lda minute
xba
and #$FF
pha
cmp #10
bcs ptime2a
lda #'0'
jsr putchar
ptime2a pla
jsr WriteNum
lda hour
and #$FF
if2 @a,cs,#12,ptime3
ptime5 lda #'a'
bra ptime4
ptime3 lda #'p'
ptime4 jsr putchar
lda #'m'
jmp _putchar
;
; Set Stand Out (turn on inverse mode)
;
pstandout jsr standout
jmp promptloop
;
; UnSet Stand Out (turn off inverse mode)
;
pstandend jsr standend
jmp promptloop
;
; Set Underline
;
punderline jsr underline
jmp promptloop
;
; UnSet Underline
;
punderend jsr underend
jmp promptloop
;
; Current working directory
;
pcwd anop
pea 0
jsl getpfxstr Get value of prefix 0.
sta pfx
stx pfx+2
ora pfx+2 If NULL pointer returned,
jeq promptloop an error was reported.
ldy #4 Text starts at byte 4.
pcwd1 lda [pfx],y Get next
and #$FF character.
beq freepfx Done when at end of string.
jsr toslash Convert to slash.
phy Hold index on stack
jsr putchar while printing character.
ply
iny Bump index
bra pcwd1 and stay in loop.
freepfx ph4 pfx Free the current directory buffer.
jsl nullfree
jmp promptloop
;
; Tail of current working directory
;
pcwdend anop
pea 0
jsl getpfxstr Get value of prefix 0.
sta pfx
stx pfx+2
ora pfx+2 If NULL pointer returned,
jeq promptloop an error was reported.
ldy #2 Get string's length word
lda [pfx],y from bytes 2 & 3.
clc Add 3 to get offset
adc #3 from beginning of buffer.
sta offset
tay
pcwdend1 dey If we've backed up to the beginning,
bmi pcwdend2 we can't go any further!
lda [pfx],y Get next character.
and #$FF
cmp #':' If it's not ':',
bne pcwdend1 keep searching backward.
pcwdend2 iny
cpy offset
jeq freepfx Free the current directory buffer.
lda [pfx],y
and #$FF
cmp #':'
jeq freepfx Free the current directory buffer.
phy
jsr putchar
ply
bra pcwdend2
;
; Current working directory substituting '~' if necessary
;
ptilde anop
pea 0
jsl getpfxstr Get value of prefix 0.
sta pfx
stx pfx+2
ora pfx+2 If NULL pointer returned,
jeq promptloop an error was reported.
lda pfx Otherwise, restore low-order address.
clc Add 4 to start of buffer
adc #4 so it can be treated like
bcc pushad a c-string.
inx
pushad phx
pha
jsl path2tilde Convert $HOME to "~"
phx Push addr onto stack
pha for nullfree.
jsr puts Print tilde string.
jsl nullfree Free the converted string.
jmp freepfx Free the current directory buffer.
;
; Write user name
;
puser ph4 #username Get value of $USER
jsl getenv
sta usergsbuf If buffer wasn't allocated
stx usergsbuf+2
ora usergsbuf+2
beq goploop ignore it.
clc
lda usergsbuf Text begins after
adc #4 four bytes of
bcc printit length words.
inx
printit jsr puts
pei (usergsbuf+2) Free $USER value buffer
pei (usergsbuf)
jsl nullfree
goploop jmp promptloop
;
; Write date as mm/dd/yy
;
pdate1 ReadTimeHex (@a,year,monday,@a)
lda monday
and #$FF00
xba
inc a
jsr WriteNum
lda #'/'
jsr putchar
lda monday
and #$FF
inc a
jsr WriteNum
lda #'/'
jsr putchar
lda year
and #$FF00
xba
jsr WriteNum
jmp promptloop
;
; Write date as yy-mm-dd
;
pdate2 ReadTimeHex (@a,year,monday,@a)
lda year
and #$FF00
xba
jsr WriteNum
lda #'-'
jsr putchar
lda monday
and #$FF00
xba
inc a
jsr WriteNum
lda #'-'
jsr putchar
lda monday
and #$FF
inc a
jsr WriteNum
jmp promptloop
;
; check for \ quote
;
quoteit lda [prompt]
incad prompt
and #$FF
jeq done
cmp #'n'
beq newline
cmp #'r'
beq newline
cmp #'t'
beq tab
cmp #'b'
beq backspace
jmp _putchar
newline lda #13
jmp _putchar
tab lda #9
jmp _putchar
backspace lda #8
jmp _putchar
;
; Write a number between 0 and 9,999
;
WriteNum cmp #10
bcs write1
adc #'0'
jmp putchar
write1 cmp #100
bcs write2
Int2Dec (@a,#num+2,#2,#0)
ldx #^num+2
lda #num+2
jmp puts
write2 cmp #1000
bcs write3
Int2Dec (@a,#num+1,#3,#0)
ldx #^num+1
lda #num+1
jmp puts
write3 Int2Dec (@a,#num,#4,#0)
ldx #^num
lda #num
jmp puts
; Name of alias to execute before prompt
precmdstr dc c'precmd',h'00'
; Names of environment variables
promptname gsstr 'prompt'
username gsstr 'user'
; Default prompt
dfltPrompt dc c'% ',h'00'
num dc c'0000',h'00'
END