mirror of
https://github.com/cc65/cc65.git
synced 2025-01-10 19:29:45 +00:00
Replaced vsscanf by an assembler version
git-svn-id: svn://svn.cc65.org/cc65/trunk@3315 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
501cc4c6c8
commit
18b154e6b1
@ -35,6 +35,5 @@ strtok.s
|
|||||||
strxfrm.s
|
strxfrm.s
|
||||||
system.s
|
system.s
|
||||||
timezone.s
|
timezone.s
|
||||||
vsscanf.s
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -64,8 +64,7 @@ C_OBJS = _afailed.o \
|
|||||||
strxfrm.o \
|
strxfrm.o \
|
||||||
strtok.o \
|
strtok.o \
|
||||||
system.o \
|
system.o \
|
||||||
timezone.o \
|
timezone.o
|
||||||
vsscanf.o
|
|
||||||
|
|
||||||
|
|
||||||
S_OBJS = _cwd.o \
|
S_OBJS = _cwd.o \
|
||||||
@ -171,6 +170,7 @@ S_OBJS = _cwd.o \
|
|||||||
vprintf.o \
|
vprintf.o \
|
||||||
vscanf.o \
|
vscanf.o \
|
||||||
vsprintf.o \
|
vsprintf.o \
|
||||||
|
vsscanf.o \
|
||||||
zerobss.o
|
zerobss.o
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,81 +0,0 @@
|
|||||||
/*
|
|
||||||
* vsscanf.c
|
|
||||||
*
|
|
||||||
* (C) Copyright 2002 Ullrich von Bassewitz (uz@cc65.org)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "_scanf.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/* Data */
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct sscanfdata {
|
|
||||||
const char* str; /* Pointer to input string */
|
|
||||||
unsigned index; /* Read index */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/* Code */
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int __fastcall__ get (struct sscanfdata* d)
|
|
||||||
/* Read a character from the input string and return it */
|
|
||||||
{
|
|
||||||
char C;
|
|
||||||
if (C = d->str[d->index]) {
|
|
||||||
/* Increment index only if end not reached */
|
|
||||||
++d->index;
|
|
||||||
return C;
|
|
||||||
} else {
|
|
||||||
return EOF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int __fastcall__ unget (int c, struct sscanfdata* d)
|
|
||||||
/* Push back a character onto the input stream */
|
|
||||||
{
|
|
||||||
/* We do assume here that the _scanf routine will not push back anything
|
|
||||||
* not read, so we can ignore c safely and won't check the index.
|
|
||||||
*/
|
|
||||||
--d->index;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int __fastcall__ vsscanf (const char* str, const char* format, va_list ap)
|
|
||||||
/* Standard C function */
|
|
||||||
{
|
|
||||||
struct sscanfdata sd;
|
|
||||||
struct scanfdata d;
|
|
||||||
|
|
||||||
/* Initialize the data structs. The sscanfdata struct will be passed back
|
|
||||||
* to the get and unget functions by _scanf.
|
|
||||||
*/
|
|
||||||
d.get = (getfunc) get;
|
|
||||||
d.unget = (ungetfunc) unget,
|
|
||||||
d.data = &sd;
|
|
||||||
sd.str = str;
|
|
||||||
sd.index = 0;
|
|
||||||
|
|
||||||
/* Call the internal function and return the result */
|
|
||||||
return _scanf (&d, format, ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
187
libsrc/common/vsscanf.s
Normal file
187
libsrc/common/vsscanf.s
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
;
|
||||||
|
; int __fastcall__ vsscanf (const char* str, const char* format, va_list ap);
|
||||||
|
; /* Standard C function */
|
||||||
|
;
|
||||||
|
; Ullrich von Bassewitz, 2004-11-28
|
||||||
|
;
|
||||||
|
|
||||||
|
.export _vsscanf
|
||||||
|
.import popax, __scanf
|
||||||
|
.importzp sp, ptr1, ptr2
|
||||||
|
|
||||||
|
.macpack generic
|
||||||
|
|
||||||
|
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
; Structure used to pass data to the callback functions
|
||||||
|
|
||||||
|
.struct SSCANFDATA
|
||||||
|
STR .addr
|
||||||
|
INDEX .word
|
||||||
|
.endstruct
|
||||||
|
|
||||||
|
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
; static int __fastcall__ get (struct sscanfdata* d)
|
||||||
|
; /* Read a character from the input string and return it */
|
||||||
|
; {
|
||||||
|
; char C;
|
||||||
|
; if (C = d->str[d->index]) {
|
||||||
|
; /* Increment index only if end not reached */
|
||||||
|
; ++d->index;
|
||||||
|
; return C;
|
||||||
|
; } else {
|
||||||
|
; return EOF;
|
||||||
|
; }
|
||||||
|
; }
|
||||||
|
;
|
||||||
|
|
||||||
|
.code
|
||||||
|
.proc get
|
||||||
|
|
||||||
|
sta ptr1
|
||||||
|
stx ptr1+1 ; Save d
|
||||||
|
|
||||||
|
; Get d->str adding the high byte of index to the pointer, so we can access
|
||||||
|
; the byte in the string with just the low byte as index
|
||||||
|
|
||||||
|
ldy #SSCANFDATA::STR
|
||||||
|
lda (ptr1),y
|
||||||
|
sta ptr2
|
||||||
|
iny
|
||||||
|
lda (ptr1),y
|
||||||
|
ldy #SSCANFDATA::INDEX+1
|
||||||
|
add (ptr1),y
|
||||||
|
sta ptr2+1
|
||||||
|
|
||||||
|
; Load the low byte of the index and fetch the byte from the string
|
||||||
|
|
||||||
|
dey ; = SSCANFDATA::INDEX
|
||||||
|
lda (ptr1),y
|
||||||
|
tay
|
||||||
|
lda (ptr2),y
|
||||||
|
|
||||||
|
; Return EOF if we are at the end of the string
|
||||||
|
|
||||||
|
bne L1
|
||||||
|
lda #$FF
|
||||||
|
tax
|
||||||
|
rts
|
||||||
|
|
||||||
|
; Bump the index (beware: A contains the char we must return)
|
||||||
|
|
||||||
|
L1: tax ; Save return value
|
||||||
|
tya ; Low byte of index
|
||||||
|
ldy #SSCANFDATA::INDEX
|
||||||
|
add #1
|
||||||
|
sta (ptr1),y
|
||||||
|
iny
|
||||||
|
lda (ptr1),y
|
||||||
|
adc #$00
|
||||||
|
sta (ptr1),y
|
||||||
|
|
||||||
|
; Return the char just read
|
||||||
|
|
||||||
|
txa
|
||||||
|
ldx #$00
|
||||||
|
rts
|
||||||
|
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
; static int __fastcall__ unget (int c, struct sscanfdata* d)
|
||||||
|
; /* Push back a character onto the input stream */
|
||||||
|
; {
|
||||||
|
; /* We do assume here that the _scanf routine will not push back anything
|
||||||
|
; * not read, so we can ignore c safely and won't check the index.
|
||||||
|
; */
|
||||||
|
; --d->index;
|
||||||
|
; return c;
|
||||||
|
; }
|
||||||
|
;
|
||||||
|
|
||||||
|
.code
|
||||||
|
.proc unget
|
||||||
|
|
||||||
|
sta ptr1
|
||||||
|
stx ptr1+1 ; Save d
|
||||||
|
|
||||||
|
; Decrement the index
|
||||||
|
|
||||||
|
ldy #SSCANFDATA::INDEX
|
||||||
|
lda (ptr1),y
|
||||||
|
sub #1
|
||||||
|
sta (ptr1),y
|
||||||
|
iny
|
||||||
|
lda (ptr1),y
|
||||||
|
sbc #0
|
||||||
|
sta (ptr1),y
|
||||||
|
|
||||||
|
; Return c
|
||||||
|
|
||||||
|
jmp popax
|
||||||
|
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
; int __fastcall__ vsscanf (const char* str, const char* format, va_list ap)
|
||||||
|
; /* Standard C function */
|
||||||
|
; {
|
||||||
|
; struct sscanfdata sd;
|
||||||
|
; struct scanfdata d;
|
||||||
|
;
|
||||||
|
; /* Initialize the data structs. The sscanfdata struct will be passed back
|
||||||
|
; * to the get and unget functions by _scanf.
|
||||||
|
; */
|
||||||
|
; d.get = (getfunc) get;
|
||||||
|
; d.unget = (ungetfunc) unget,
|
||||||
|
; d.data = &sd;
|
||||||
|
; sd.str = str;
|
||||||
|
; sd.index = 0;
|
||||||
|
;
|
||||||
|
; /* Call the internal function and return the result */
|
||||||
|
; return _scanf (&d, format, ap);
|
||||||
|
; }
|
||||||
|
;
|
||||||
|
|
||||||
|
.data
|
||||||
|
|
||||||
|
sd: .tag SSCANFDATA
|
||||||
|
|
||||||
|
d: .addr get
|
||||||
|
.addr unget
|
||||||
|
.addr sd
|
||||||
|
|
||||||
|
.code
|
||||||
|
.proc _vsscanf
|
||||||
|
|
||||||
|
; Save the low byte of ap (which is passed in a/x)
|
||||||
|
|
||||||
|
pha
|
||||||
|
|
||||||
|
; Initialize sd and at the same time replace str on the stack by a pointer
|
||||||
|
; to d
|
||||||
|
|
||||||
|
ldy #2 ; Stack offset of str
|
||||||
|
lda (sp),y
|
||||||
|
sta sd + SSCANFDATA::STR
|
||||||
|
lda #<d
|
||||||
|
sta (sp),y
|
||||||
|
iny
|
||||||
|
lda (sp),y
|
||||||
|
sta sd + SSCANFDATA::STR+1
|
||||||
|
lda #>d
|
||||||
|
sta (sp),y
|
||||||
|
|
||||||
|
lda #$00
|
||||||
|
sta sd + SSCANFDATA::INDEX
|
||||||
|
sta sd + SSCANFDATA::INDEX+1
|
||||||
|
|
||||||
|
; Restore the low byte of ap and jump to _scanf which will cleanup the stacl
|
||||||
|
|
||||||
|
pla
|
||||||
|
jmp __scanf
|
||||||
|
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user