mirror of
https://github.com/GnoConsortium/gno.git
synced 2025-01-06 19:30:34 +00:00
05d82736bc
Add check for buffer overflow when globbing, expanding variables, or inserting aliases (PR#110). Increase buffer size from 1024 to 4096. Increase buffer for reading commands from 256 to 1024 bytes in order to match the maximum length used when reading.
787 lines
16 KiB
NASM
787 lines
16 KiB
NASM
**************************************************************************
|
|
*
|
|
* The GNO Shell Project
|
|
*
|
|
* Developed by:
|
|
* Jawaid Bazyar
|
|
* Tim Meekins
|
|
*
|
|
* $Id: expand.asm,v 1.8 1999/02/08 17:26:50 tribby Exp $
|
|
*
|
|
**************************************************************************
|
|
*
|
|
* EXPAND.ASM
|
|
* By Tim Meekins
|
|
* Modified by Dave Tribby for GNO 2.0.6
|
|
*
|
|
* Command line expansion routines for wildcards and env vars
|
|
*
|
|
* Note: text set up for tabs at col 16, 22, 41, 49, 57, 65
|
|
* | | | | | |
|
|
* ^ ^ ^ ^ ^ ^
|
|
**************************************************************************
|
|
|
|
mcopy /obj/gno/bin/gsh/expand.mac
|
|
|
|
dummyexpand start ; ends up in .root
|
|
end
|
|
|
|
setcom 60
|
|
|
|
**************************************************************************
|
|
*
|
|
* glob the command line and expand filename wildcard characters
|
|
*
|
|
**************************************************************************
|
|
|
|
glob START
|
|
|
|
using vardata
|
|
|
|
count equ 0
|
|
gname equ count+2
|
|
sepptr equ gname+4
|
|
eptr equ sepptr+4
|
|
exppath equ eptr+4
|
|
filesep equ exppath+4
|
|
shallweglob equ filesep+2
|
|
wordbuf equ shallweglob+2
|
|
index equ wordbuf+4
|
|
buf equ index+2
|
|
globflag equ buf+4
|
|
overflag equ globflag+2
|
|
space equ overflag+2
|
|
|
|
subroutine (4:cmd),space
|
|
|
|
; Allocate buffer to hold result
|
|
jsl allocmaxline
|
|
sta buf
|
|
stx buf+2
|
|
|
|
; Check for noglob variable and exit if it's set to something.
|
|
ldy varnoglob
|
|
beq doglob
|
|
|
|
; Allocate a buffer, copy the command line into it, and return.
|
|
pei (cmd+2)
|
|
pei (cmd)
|
|
pei (buf+2)
|
|
pei (buf)
|
|
jsr copycstr
|
|
jmp bye
|
|
|
|
;
|
|
; noglob isn't set, so we can start globbing.
|
|
;
|
|
doglob lda #$FFFF Start output index at -1.
|
|
sta index
|
|
|
|
jsl allocmaxline Create a word buffer.
|
|
sta wordbuf
|
|
stx wordbuf+2
|
|
|
|
jsl allocmaxline Alloc buffer for wildcard pattern.
|
|
sta exppath
|
|
stx exppath+2
|
|
|
|
ph4 #65 Allocate memory for
|
|
~NEW expanded name.
|
|
sta gname Store in direct
|
|
stx gname+2 page pointer
|
|
|
|
stz globflag globflag = no globbing done (yet).
|
|
stz overflag Clear output buffer overflow flag.
|
|
|
|
;
|
|
; Find the beginning of the next word
|
|
;
|
|
findword jsr g_getbyte Get character from command line.
|
|
jeq alldone
|
|
if2 @a,eq,#' ',passthru
|
|
if2 @a,eq,#009,passthru
|
|
if2 @a,eq,#013,passthru
|
|
if2 @a,eq,#010,passthru
|
|
if2 @a,eq,#';',passthru
|
|
if2 @a,eq,#'&',passthru
|
|
if2 @a,eq,#'|',passthru
|
|
if2 @a,eq,#'>',passthru
|
|
if2 @a,eq,#'<',passthru
|
|
|
|
; It's not a simple pass-through character. See what needs to happen.
|
|
|
|
stz shallweglob
|
|
ldy #0
|
|
bra grabbingword
|
|
|
|
; For pass-through characters, just copy to output buffer.
|
|
|
|
passthru jsr g_putbyte
|
|
bra findword
|
|
|
|
;
|
|
; single out the next word [y is initialized above]
|
|
;
|
|
grabword jsr g_getbyte
|
|
grabbingword if2 @a,eq,#"'",grabsingle
|
|
if2 @a,eq,#'"',grabdouble
|
|
if2 @a,eq,#'\',grabslash
|
|
if2 @a,eq,#' ',procword
|
|
if2 @a,eq,#009,procword
|
|
if2 @a,eq,#013,procword
|
|
if2 @a,eq,#010,procword
|
|
if2 @a,eq,#000,procword
|
|
if2 @a,eq,#';',procword
|
|
if2 @a,eq,#'&',procword
|
|
if2 @a,eq,#'|',procword
|
|
if2 @a,eq,#'>',procword
|
|
if2 @a,eq,#'<',procword
|
|
if2 @a,eq,#'[',grabglob
|
|
if2 @a,eq,#']',grabglob
|
|
if2 @a,eq,#'*',grabglob
|
|
if2 @a,eq,#'?',grabglob
|
|
|
|
; Default action (also completion of some of the other special cases)
|
|
grabnext sta [wordbuf],y Save character in word buffer
|
|
iny and bump its index.
|
|
bra grabword Get next character of word.
|
|
|
|
; "[", "]", "*", "?"
|
|
grabglob ldx #1 Set "shallweglob"
|
|
stx shallweglob flag.
|
|
bra grabnext Store char in word buf & get next.
|
|
|
|
; "\"
|
|
grabslash sta [wordbuf],y Save "\" in word buffer
|
|
iny and bump its index.
|
|
jsr g_getbyte Get next character in cmd line.
|
|
beq procword If null byte, word is terminated.
|
|
bra grabnext Store char in word buf & get next.
|
|
|
|
; '"'
|
|
grabsingle sta [wordbuf],y Save char in word buffer
|
|
iny and bump its index.
|
|
jsr g_getbyte Get next character in cmd line.
|
|
beq procword If null byte, word is terminated.
|
|
if2 @a,eq,#"'",grabnext If "'", store and grab next char.
|
|
bra grabsingle Save new char and stay in this loop.
|
|
|
|
; "'"
|
|
grabdouble sta [wordbuf],y Save char in word buffer
|
|
iny and bump its index.
|
|
jsr g_getbyte Get next character in cmd line.
|
|
beq procword If null byte, word is terminated.
|
|
if2 @a,eq,#'"',grabnext If '"', store and grab next char.
|
|
bra grabdouble Save new char and stay in this loop.
|
|
|
|
|
|
;
|
|
; The complete word is in the buffer. Time to process it.
|
|
;
|
|
procword dec cmd Decrement cmd line pointer.
|
|
lda #0 Terminate word buffer with
|
|
sta [wordbuf],y a null byte.
|
|
|
|
;
|
|
; Shall we glob? Shall we scream? What happened, to our postwar dream?
|
|
;
|
|
lda [wordbuf]
|
|
and #$FF
|
|
if2 @a,eq,#'-',skipdeglob ;This allows '-?' option.
|
|
lda shallweglob
|
|
bne globword
|
|
;
|
|
; we didn't glob this word, so copy the word buffer to the output buffer
|
|
;
|
|
skipdeglob ldy #0
|
|
flushloop lda [wordbuf],y
|
|
and #$FF
|
|
beq doneflush
|
|
jsr g_putbyte
|
|
iny
|
|
bra flushloop
|
|
doneflush anop
|
|
lda overflag If buffer overflowed,
|
|
jne errexit clean up and return null pointer.
|
|
jmp findword
|
|
|
|
;
|
|
; Hello, boys and goils, velcome to Tim's Magik Shoppe
|
|
;
|
|
; Ok, here's the plan:
|
|
; 1. We give InitWildcardGS a PATHNAME.
|
|
; 2. NextWildcardGS returns a FILENAME.
|
|
; 3. We need to expand to the command-line the full pathname.
|
|
; 4. Therefore, we must put aside the prefix, and cat each file returned
|
|
; from NextWildcardGS to the saved prefix, but, we must still pass
|
|
; the entire path to InitWildcardGS.
|
|
; 5. This solves our problem with quoting. Expand the quotes before
|
|
; passing along to InitWildcardGS, BUT the saved prefix we saved to cat
|
|
; to will still have the quotes in it, so that the tokenizer can deal
|
|
; with it. Whew!
|
|
;
|
|
; Well, here goes nuthin'.... [Ya know, and I'm reading Levy's book
|
|
; 'Hackers' right now...]
|
|
;
|
|
;
|
|
;
|
|
; Expand out the quoted stuff, and keep an eye out for that ubiquitous last
|
|
; filename separator... then we can isolate him!
|
|
;
|
|
globword stz filesep
|
|
|
|
lda exppath Get addr of wildcard
|
|
ldx exppath+2 pattern buffer.
|
|
incad @xa Leave room for length word
|
|
incad @xa
|
|
sta eptr
|
|
stx eptr+2
|
|
sta sepptr
|
|
stx sepptr+2
|
|
|
|
ldy #0
|
|
exploop lda [wordbuf],y
|
|
and #$FF
|
|
beq endexp
|
|
iny
|
|
if2 @a,eq,#'\',expslash
|
|
if2 @a,eq,#"'",expsingle
|
|
if2 @a,eq,#'"',expdouble
|
|
if2 @a,eq,#'/',expsep
|
|
if2 @a,eq,#':',expsep
|
|
expput sta [eptr]
|
|
incad eptr
|
|
bra exploop
|
|
expsep sty filesep
|
|
sta [eptr]
|
|
incad eptr
|
|
mv4 eptr,sepptr
|
|
bra exploop
|
|
expslash lda [wordbuf],y
|
|
iny
|
|
and #$FF
|
|
beq endexp
|
|
bra expput
|
|
expsingle lda [wordbuf],y
|
|
iny
|
|
and #$FF
|
|
beq endexp
|
|
if2 @a,eq,#"'",exploop
|
|
sta [eptr]
|
|
incad eptr
|
|
bra expsingle
|
|
expdouble lda [wordbuf],y
|
|
iny
|
|
and #$FF
|
|
beq endexp
|
|
if2 @a,eq,#'"',exploop
|
|
sta [eptr]
|
|
incad eptr
|
|
bra expdouble
|
|
;
|
|
; We really didn't mean to expand the filename, so, copy it back again..
|
|
;
|
|
endexp ldy filesep
|
|
copyback lda [wordbuf],y
|
|
iny
|
|
and #$FF
|
|
sta [sepptr]
|
|
incad sepptr
|
|
cmp #0
|
|
bne copyback
|
|
;
|
|
; Calculate length by subtracting sepptr from starting address
|
|
;
|
|
sub2 sepptr,exppath,@a
|
|
dec2 a Don't count length word or \0
|
|
dec a
|
|
sta [exppath]
|
|
;
|
|
; We now have enough to call InitWildCardGS!!!
|
|
; [ let's mutex the rest so we don't have to fix InitWC and NextWC ;-) ]
|
|
;
|
|
lock glob_mutex
|
|
;
|
|
; Call shell routine InitWildcardGS to initialize the filename pattern
|
|
;
|
|
stz count
|
|
mv4 exppath,initWCpath
|
|
InitWildcardGS initWCparm
|
|
|
|
lda gname Store expanded
|
|
ldx gname+2 name addr
|
|
sta nWCname in NextWildcardGS
|
|
stx nWCname+2 parameter block.
|
|
lda #65 Store maximum length at
|
|
sta [gname] beginning of result buf.
|
|
;
|
|
; Call shell routine NextWildcardGS to get the next name that matches.
|
|
;
|
|
WCloop anop
|
|
lda overflag If buffer overflowed,
|
|
bne nomore quit expanding.
|
|
NextWildcardGS nWCparm
|
|
ldy #2
|
|
lda [gname],y
|
|
beq nomore
|
|
;
|
|
; Keep count of how many paths are expanded
|
|
;
|
|
inc count
|
|
|
|
;
|
|
; Copy the original path (up to file separator) to output buffer
|
|
;
|
|
ldy #0
|
|
outtahere if2 @y,eq,filesep,globout
|
|
lda [wordbuf],y
|
|
jsr g_putspecial
|
|
iny
|
|
bra outtahere
|
|
;
|
|
; Copy the expanded filename to output buffer
|
|
;
|
|
globout ldy #2 Get returned length
|
|
lda [gname],y from GS/OS buffer.
|
|
tax
|
|
ldy #4
|
|
globoutta lda [gname],y Copy next character
|
|
jsr g_putspecial into buffer.
|
|
iny
|
|
dex
|
|
bne globoutta
|
|
;
|
|
; Place blank as separator after name and see if more are expanded.
|
|
;
|
|
lda #' '
|
|
jsr g_putbyte
|
|
bra WCloop
|
|
|
|
;
|
|
; All of the names (if any) from this pattern have been expanded.
|
|
;
|
|
nomore anop
|
|
|
|
unlock glob_mutex
|
|
|
|
lda overflag If buffer overflowed,
|
|
bne errexit clean up and return null pointer.
|
|
|
|
lda count If something was expanded,
|
|
beq nothingfound
|
|
|
|
lda globflag Set "globbed, something found"
|
|
ora #$8000 bit in globflag.
|
|
sta globflag
|
|
jmp findword Go find the next word.
|
|
|
|
; Nothing was expanded from the wildcard. If we wanted to act like
|
|
; ksh, we could pass the original text by doing a "jmp skipdeglob".
|
|
|
|
nothingfound anop
|
|
lda globflag Set "globbed, nothing found"
|
|
ora #$4000 bit in globflag.
|
|
sta globflag
|
|
|
|
jmp findword Go find the next word.
|
|
|
|
;
|
|
; Goodbye, cruel world, I'm leaving you today, Goodbye, goodbye.
|
|
;
|
|
alldone anop
|
|
jsr g_putbyte Store null byte at end of string.
|
|
lda overflag If buffer overflowed,
|
|
bne errexit clean up and return null ptr.
|
|
;
|
|
; Check globflag for no valid matches found in any pattern
|
|
;
|
|
lda globflag
|
|
cmp #$4000
|
|
bne alldone2
|
|
|
|
ldx #^nomatch
|
|
lda #nomatch
|
|
jsr errputs
|
|
|
|
errexit ldx buf+2
|
|
lda buf
|
|
jsl freemaxline
|
|
|
|
stz buf+2 Return NULL
|
|
stz buf value from routine.
|
|
|
|
alldone2 ldx wordbuf+2
|
|
lda wordbuf
|
|
jsl freemaxline
|
|
|
|
pei (gname+2)
|
|
pei (gname)
|
|
jsl nullfree
|
|
|
|
ldx exppath+2
|
|
lda exppath
|
|
jsl freemaxline
|
|
|
|
bye return 4:buf
|
|
|
|
|
|
;
|
|
; Subroutine of glob: get a byte from the original command-line
|
|
;
|
|
g_getbyte lda [cmd]
|
|
incad cmd
|
|
and #$FF
|
|
rts
|
|
|
|
;
|
|
; Subroutine of glob: put special characters. Same as g_putbyte, but
|
|
; if it is a special shell character then quote it.
|
|
;
|
|
g_putspecial and #$7F
|
|
if2 @a,eq,#' ',special
|
|
; if2 @a,eq,#'.',special >> NOTE: '.' isn't special!
|
|
if2 @a,eq,#013,special
|
|
if2 @a,eq,#009,special
|
|
if2 @a,eq,#';',special
|
|
if2 @a,eq,#'&',special
|
|
if2 @a,eq,#'<',special
|
|
if2 @a,eq,#'>',special
|
|
if2 @a,eq,#'|',special
|
|
bra g_putbyte
|
|
special pha
|
|
lda #'\'
|
|
jsr g_putbyte
|
|
pla ; fall through to g_putbyte...
|
|
;
|
|
; Subroutine of glob: store a byte into the new command-line
|
|
;
|
|
g_putbyte anop
|
|
phx Hold X-reg on stack.
|
|
inc index Bump the buffer index.
|
|
ldx index
|
|
cpx maxline_size
|
|
bcc nooverflow If more chars than will fit in buffer:
|
|
lda overflag If already reported,
|
|
bne ovflwreturn return to caller.
|
|
inc overflag Set overflow flag.
|
|
ldx #^ovferr Report overflow error.
|
|
lda #ovferr
|
|
jsr errputs
|
|
bra ovflwreturn Return to caller.
|
|
nooverflow phy Hold Y-reg on stack.
|
|
txy
|
|
short a
|
|
sta [buf],y Store character in output buffer.
|
|
long a
|
|
ply Restore Y-reg.
|
|
ovflwreturn plx Restore X-reg.
|
|
rts
|
|
|
|
ovferr dc c'gsh: Globbing overflowed line limit',h'0d00'
|
|
|
|
glob_mutex key
|
|
|
|
;
|
|
; Parameter block for shell InitWildcardGS call (p 414 in ORCA/M manual)
|
|
;
|
|
InitWCParm dc i2'2' pCount
|
|
InitWCPath ds 4 Path name, with wildcard
|
|
dc i2'%00000001' Flags (this bit not documented!!!)
|
|
|
|
;
|
|
; Parameter block for shell NextWildcardGS call (p 414 in ORCA/M manual)
|
|
;
|
|
nWCparm dc i2'1' pCount
|
|
nWCname ds 4 Pointer to returned path name
|
|
|
|
nomatch dc c'No match',h'0d00'
|
|
|
|
END
|
|
|
|
**************************************************************************
|
|
*
|
|
* Expand $variables and tildes not in single quotes
|
|
*
|
|
**************************************************************************
|
|
|
|
expandvars START
|
|
|
|
; Maximum number of characters in an environment variable or $<
|
|
MAXVAL equ 512
|
|
|
|
|
|
index equ 1
|
|
buf equ index+2
|
|
dflag equ buf+4
|
|
overflag equ dflag+2
|
|
space equ overflag+2
|
|
cmd equ space+3
|
|
end equ cmd+4
|
|
|
|
; subroutine (4:cmd),space
|
|
|
|
tsc
|
|
sec
|
|
sbc #space-1
|
|
tcs
|
|
phd
|
|
tcd
|
|
|
|
stz dflag Delimiter flag = FALSE.
|
|
stz overflag Clear output buffer overflow flag.
|
|
lda #$FFFF Start output index at -1.
|
|
sta index
|
|
|
|
jsl allocmaxline
|
|
sta buf
|
|
stx buf+2
|
|
|
|
loop jsr e_getbyte
|
|
jeq done
|
|
if2 @a,eq,#"'",quote
|
|
if2 @a,eq,#'$',expand
|
|
if2 @a,eq,#'~',tilde
|
|
if2 @a,eq,#'\',slasher
|
|
jsr e_putbyte
|
|
bra loop
|
|
|
|
slasher jsr e_putbyte
|
|
jsr e_getbyte
|
|
jsr e_putbyte
|
|
bra loop
|
|
|
|
quote jsr e_putbyte
|
|
jsr e_getbyte
|
|
jeq done
|
|
if2 @a,ne,#"'",quote
|
|
jsr e_putbyte
|
|
bra loop
|
|
|
|
;
|
|
; Tilde expansion: use the contents of $home, but make sure the
|
|
; path delimiter(s) match what the user wants (either "/" or ":")
|
|
;
|
|
tilde anop
|
|
lock exp_mutex
|
|
|
|
lda #"oh" Strangely enough,
|
|
sta name this spells "home"!
|
|
lda #"em"
|
|
sta name+2
|
|
sta dflag Delimiter flag = TRUE.
|
|
ldx #4
|
|
jmp getval
|
|
|
|
;
|
|
; Expand an environment variable since a '$' was encountered.
|
|
;
|
|
expand anop
|
|
lock exp_mutex
|
|
|
|
lda #0
|
|
sta name
|
|
lda [cmd]
|
|
and #$FF
|
|
if2 @a,eq,#'{',braceexpand
|
|
if2 @a,eq,#'<',stdinexpand
|
|
ldx #0
|
|
nameloop lda [cmd]
|
|
and #$FF
|
|
beq getval
|
|
if2 @a,cc,#'0',getval
|
|
if2 @a,cc,#'9'+1,inname
|
|
if2 @a,cc,#'A',getval
|
|
if2 @a,cc,#'Z'+1,inname
|
|
if2 @a,eq,#'_',inname
|
|
if2 @a,cc,#'a',getval
|
|
if2 @a,cc,#'z'+1,inname
|
|
bra getval
|
|
inname jsr e_getbyte
|
|
cpx #255 Only the first 255 characters
|
|
beq nameloop are significant.
|
|
sta name,x
|
|
inx
|
|
bra nameloop
|
|
|
|
;
|
|
; expand in braces {}
|
|
;
|
|
braceexpand jsr e_getbyte
|
|
ldx #0
|
|
braceloop lda [cmd]
|
|
and #$FF
|
|
beq getval
|
|
jsr e_getbyte
|
|
if2 @a,eq,#'}',getval
|
|
cpx #255 Only the first 255 characters
|
|
beq braceloop are significant.
|
|
sta name,x
|
|
inx
|
|
bra braceloop
|
|
|
|
;
|
|
; get text from standard input
|
|
;
|
|
stdinexpand jsr e_getbyte
|
|
ReadLine (#value,#MAXVAL,#13,#0),@a
|
|
sta valueln
|
|
bra chklen
|
|
|
|
;
|
|
; Get a value for this variable
|
|
;
|
|
getval stx nameln Save length of name.
|
|
ReadVariableGS ReadVarPB Read its value.
|
|
|
|
lda valueln Get value length.
|
|
cmp #MAXVAL+1 If > maximum allowed length,
|
|
bcs expanded we didn't get anything.
|
|
cmp #0
|
|
chklen anop
|
|
beq expanded If 0, nothing to do
|
|
tax Save length in X-reg.
|
|
lda dflag If delimiter flag isn't set,
|
|
beq storeval go store the variable value
|
|
|
|
; Check to see if delimiters in the variable need to be switched
|
|
lda valueln Set up length in
|
|
tax X-reg and get
|
|
lda [cmd] next command line
|
|
and #$FF character.
|
|
cmp #"/" If it's a slash, see if
|
|
beq chkvarslash variable needs to convert to slash.
|
|
cmp #":" If it's not a colon,
|
|
bne storeval no need to convert.
|
|
lda value Get first character of value.
|
|
and #$FF
|
|
cmp #"/" If it's not a slash,
|
|
bne storeval no need to convert.
|
|
|
|
; Convert variable from "/" to ":" delimiter
|
|
short m
|
|
chk_s lda value-1,x
|
|
cmp #"/"
|
|
bne bump_s
|
|
lda #":"
|
|
sta value-1,x
|
|
bump_s dex
|
|
bpl chk_s
|
|
long m
|
|
bra storeval
|
|
|
|
chkvarslash anop
|
|
lda value Get first character of value.
|
|
and #$FF
|
|
cmp #":" If it's not a colon,
|
|
bne storeval no need to convert.
|
|
|
|
; Convert variable from ":" to "/" delimiter
|
|
short m
|
|
chk_c lda value-1,x
|
|
cmp #":"
|
|
bne bump_c
|
|
lda #"/"
|
|
sta value-1,x
|
|
bump_c dex
|
|
bpl chk_c
|
|
long m
|
|
|
|
;
|
|
; Store the variable's value in the out buffer
|
|
;
|
|
storeval anop
|
|
lda valueln Get length.
|
|
tay Save length in Y-reg.
|
|
ldx #0 Use X-reg in index value.
|
|
putval lda value,x
|
|
jsr e_putbyte
|
|
inx
|
|
dey
|
|
bne putval
|
|
|
|
expanded unlock exp_mutex
|
|
stz dflag Delimiter flag = FALSE.
|
|
lda overflag If no buffer overflow,
|
|
jeq loop stay in loop.
|
|
|
|
done jsr e_putbyte Store terminating null char.
|
|
ldx buf+2 Set return value
|
|
ldy buf to buffer pointer.
|
|
lda overflag If buffer overflowed,
|
|
beq return
|
|
tya
|
|
jsl freemaxline Free the output buffer
|
|
ldx #0 and set return pointer
|
|
ldy #0 to NULL.
|
|
|
|
return lda space
|
|
sta end-3
|
|
lda space+1
|
|
sta end-2
|
|
pld
|
|
tsc
|
|
clc
|
|
adc #end-4
|
|
tcs
|
|
|
|
tya
|
|
rtl
|
|
|
|
;
|
|
; expandvars internal subroutines to get and put bytes in buffers
|
|
;
|
|
|
|
e_getbyte lda [cmd]
|
|
incad cmd
|
|
and #$FF
|
|
rts
|
|
|
|
e_putbyte anop
|
|
phx Hold X-reg on stack.
|
|
inc index Bump the buffer index.
|
|
ldx index
|
|
cpx maxline_size
|
|
bcc nooverflow If more chars than will fit in buffer:
|
|
lda overflag If already reported,
|
|
bne ovflwreturn return to caller.
|
|
inc overflag Set overflow flag.
|
|
ldx #^ovferr Report overflow error.
|
|
lda #ovferr
|
|
jsr errputs
|
|
bra ovflwreturn Return to caller.
|
|
nooverflow phy Hold Y-reg on stack.
|
|
txy
|
|
short a
|
|
sta [buf],y Store character in output buffer.
|
|
long a
|
|
ply Restore Y-reg.
|
|
ovflwreturn plx Restore X-reg.
|
|
rts
|
|
|
|
ovferr dc c'gsh: Variable expansion overflowed line limit',h'0d00'
|
|
|
|
exp_mutex key
|
|
|
|
|
|
; GS/OS string to hold variable name
|
|
namestr anop
|
|
nameln ds 2 Length of name
|
|
name ds 256 Room for 255 chars + 0.
|
|
|
|
|
|
; GS/OS result buffer to hold up to MAXVAL bytes of value
|
|
valueresult anop
|
|
dc i2'MAXVAL+4' Length of result buffer
|
|
valueln ds 2 Length of value
|
|
value ds MAXVAL Room for MAXVAL chars
|
|
|
|
|
|
; Parameter block for shell ReadVariableGS calls
|
|
ReadVarPB anop
|
|
dc i2'3' pCount
|
|
RVname dc a4'namestr' Name (pointer to GS/OS string)
|
|
RVvalue dc a4'valueresult' Value (ptr to result buf or string)
|
|
RVexport ds 2 Export flag
|
|
|
|
END
|