Add an implementation of the <locale.h> functions.

This is currently a minimalistic implementation, which only supports the C locale.
This commit is contained in:
Stephen Heumann 2021-09-30 18:34:54 -05:00
parent 5ad86f4a0b
commit 512fadeff0
3 changed files with 202 additions and 2 deletions

107
locale.asm Normal file
View File

@ -0,0 +1,107 @@
keep obj/locale
mcopy locale.macros
case on
****************************************************************
*
* Locale - locale support
*
* This currently implements a minimalistic version of the
* <locale.h> functions, supporting only the "C" locale.
*
****************************************************************
*
Locale private dummy routine
end
****************************************************************
*
* char *setlocale(int category, const char *locale);
*
* Set or query current locale
*
* Inputs:
* category - locale category to set or query
* locale - locale name (or NULL for query)
*
* Outputs:
* returns locale string (for relevant category),
* or NULL if locale cannot be set as requested
*
****************************************************************
*
setlocale start
LC_MAX equ 5 maximum valid LC_* value
csubroutine (2:category,4:locale),0
lda category if category is invalid
cmp #LC_MAX+1
bge err return NULL
lda locale if querying the current locale
ora locale+2
beq good return "C"
lda [locale]
cmp #'C' if locale is "C" or "", we are good
beq good
and #$00FF
bne err
good lda #C_str if successful, return "C"
sta locale
lda #^C_str
sta locale+2
bra ret
err stz locale otherwise, return NULL for error
stz locale+2
ret creturn 4:locale
C_str dc c'C',i1'0'
end
****************************************************************
*
* struct lconv *localeconv(void);
*
* Get numeric formatting conventions
*
* Outputs:
* returns pointer to a struct lconv containing
* appropriate values for the current locale
*
****************************************************************
*
localeconv start
CHAR_MAX equ 255
ldx #^C_locale_lconv
lda #C_locale_lconv
rtl
C_locale_lconv anop
decimal_point dc a4'period'
thousands_sep dc a4'emptystr'
grouping dc a4'emptystr'
mon_decimal_point dc a4'emptystr'
mon_thousands_sep dc a4'emptystr'
mon_grouping dc a4'emptystr'
positive_sign dc a4'emptystr'
negative_sign dc a4'emptystr'
currency_symbol dc a4'emptystr'
frac_digits dc i1'CHAR_MAX'
p_cs_precedes dc i1'CHAR_MAX'
n_cs_precedes dc i1'CHAR_MAX'
p_sep_by_space dc i1'CHAR_MAX'
n_sep_by_space dc i1'CHAR_MAX'
p_sign_posn dc i1'CHAR_MAX'
n_sign_posn dc i1'CHAR_MAX'
int_curr_symbol dc a4'emptystr'
int_frac_digits dc i1'CHAR_MAX'
int_p_cs_precedes dc i1'CHAR_MAX'
int_n_cs_precedes dc i1'CHAR_MAX'
int_p_sep_by_space dc i1'CHAR_MAX'
int_n_sep_by_space dc i1'CHAR_MAX'
int_p_sign_posn dc i1'CHAR_MAX'
int_n_sign_posn dc i1'CHAR_MAX'
period dc c'.',i1'0'
emptystr dc i1'0'
end

93
locale.macros Normal file
View File

@ -0,0 +1,93 @@
MACRO
&lab csubroutine &parms,&work
&lab anop
aif c:&work,.a
lclc &work
&work setc 0
.a
gbla &totallen
gbla &worklen
&worklen seta &work
&totallen seta 0
aif c:&parms=0,.e
lclc &len
lclc &p
lcla &i
&i seta 1
.b
&p setc &parms(&i)
&len amid &p,2,1
aif "&len"=":",.c
&len amid &p,1,2
&p amid &p,4,l:&p-3
ago .d
.c
&len amid &p,1,1
&p amid &p,3,l:&p-2
.d
&p equ &totallen+4+&work
&totallen seta &totallen+&len
&i seta &i+1
aif &i<=c:&parms,^b
.e
tsc
aif &work=0,.f
sec
sbc #&work
tcs
.f
phd
tcd
mend
MACRO
&lab creturn &r
&lab anop
lclc &len
aif c:&r,.a
lclc &r
&r setc 0
&len setc 0
ago .h
.a
&len amid &r,2,1
aif "&len"=":",.b
&len amid &r,1,2
&r amid &r,4,l:&r-3
ago .c
.b
&len amid &r,1,1
&r amid &r,3,l:&r-2
.c
aif &len<>2,.d
ldy &r
ago .h
.d
aif &len<>4,.e
ldx &r+2
ldy &r
ago .h
.e
aif &len<>10,.g
ldy #&r
ldx #^&r
ago .h
.g
mnote 'Not a valid return length',16
mexit
.h
aif &totallen=0,.i
lda &worklen+2
sta &worklen+&totallen+2
lda &worklen+1
sta &worklen+&totallen+1
.i
pld
tsc
clc
adc #&worklen+&totallen
tcs
aif &len=0,.j
tya
.j
rtl
mend

4
make
View File

@ -19,7 +19,7 @@ if {#} == 0
unset exit
end
for i in cc ctype string stdlib time setjmp orca fcntl vars toolglue signal int64 fenv fpextra math2
for i in cc ctype string stdlib time setjmp orca fcntl vars toolglue signal int64 fenv fpextra math2 locale
Newer obj/{i}.a {i}.asm
if {Status} != 0
set exit on
@ -40,7 +40,7 @@ delete orcalib
set list vars.a assert.a cc.a setjmp.a ctype.a string.a stdlib.a
set list {list} time.a signal.a toolglue.a orca.a fcntl.a stdio.a int64.a
set list {list} fenv.a fpextra.a math2.a
set list {list} fenv.a fpextra.a math2.a locale.a
for i in {list}
echo makelib orcalib +obj/{i}
makelib orcalib +obj/{i}