Merge branch 'cc65:master' into master
This commit is contained in:
@@ -354,6 +354,7 @@ usage.
|
||||
<item>allow_lowercase
|
||||
<item>beep
|
||||
<item>dir_entry_count
|
||||
<item>get_tv
|
||||
<item>get_ostype
|
||||
<item>gmtime_dt
|
||||
<item>mktime_dt
|
||||
|
||||
@@ -333,6 +333,7 @@ usage.
|
||||
<item>_datetime
|
||||
<item>beep
|
||||
<item>dir_entry_count
|
||||
<item>get_tv
|
||||
<item>get_ostype
|
||||
<item>gmtime_dt
|
||||
<item>mktime_dt
|
||||
|
||||
@@ -833,11 +833,9 @@ names like "Loop". Here is an example:
|
||||
<sect1>Unnamed labels<p>
|
||||
|
||||
If you really want to write messy code, there are also unnamed labels. To define
|
||||
an unnamed label, use either <tt>@:</tt> (<tt>.LOCALCHAR</tt> is respected if it
|
||||
is set) or sole <tt>:</tt>.
|
||||
an unnamed label, use sole <tt>:</tt>.
|
||||
|
||||
To reference an unnamed label, use <tt>@</tt> (<tt>.LOCALCHAR</tt> is respected
|
||||
if it is set) or <tt>:</tt> with several <tt>-</tt> or <tt>+</tt> characters.
|
||||
To reference an unnamed label, use <tt>:</tt> with several <tt>-</tt> or <tt>+</tt> characters.
|
||||
The <tt>-</tt> characters will create a back reference (n'th label backwards),
|
||||
the <tt>+</tt> will create a forward reference (n'th label in forward direction).
|
||||
As an alternative, angle brackets <tt><</tt> and <tt>></tt> may be used
|
||||
@@ -847,12 +845,12 @@ Example:
|
||||
|
||||
<tscreen><verb>
|
||||
cpy #0
|
||||
beq @++
|
||||
@:
|
||||
beq :++
|
||||
:
|
||||
sta $2007
|
||||
dey
|
||||
bne @-
|
||||
@:
|
||||
bne :-
|
||||
:
|
||||
rts
|
||||
</verb></tscreen>
|
||||
|
||||
|
||||
@@ -1053,6 +1053,16 @@ This cc65 version has some extensions to the ISO C standard.
|
||||
unsigned char foo = 0b101; // sets it to 5
|
||||
</verb></tscreen>
|
||||
|
||||
<item> The character escape '\e', a GCC C extension, is accepted.
|
||||
In ASCII this is the escape character 0x1B, which may be
|
||||
remapped in other character sets via a #pragma charmap.
|
||||
It can be disabled with the <tt><ref id="option--standard"
|
||||
name="--standard"></tt> option.
|
||||
|
||||
<tscreen><verb>
|
||||
unsigned char foo = '\e'; // sets it to 0x1B or equivalent
|
||||
</verb></tscreen>
|
||||
|
||||
</itemize>
|
||||
<p>
|
||||
|
||||
|
||||
@@ -98,6 +98,7 @@ function.
|
||||
<item>allow_lowercase
|
||||
<item><ref id="beep" name="beep">
|
||||
<item><ref id="dir_entry_count" name="dir_entry_count">
|
||||
<item><ref id="get_tv" name="get_tv">
|
||||
<item><ref id="get_ostype" name="get_ostype">
|
||||
<item><ref id="gmtime_dt" name="gmtime_dt">
|
||||
<item><ref id="mktime_dt" name="mktime_dt">
|
||||
@@ -111,6 +112,7 @@ function.
|
||||
<item>_dos_type
|
||||
<item><ref id="beep" name="beep">
|
||||
<item><ref id="dir_entry_count" name="dir_entry_count">
|
||||
<item><ref id="get_tv" name="get_tv">
|
||||
<item><ref id="get_ostype" name="get_ostype">
|
||||
<item><ref id="gmtime_dt" name="gmtime_dt">
|
||||
<item><ref id="mktime_dt" name="mktime_dt">
|
||||
@@ -140,7 +142,7 @@ function.
|
||||
<!-- <item><ref id="_setcolor_low" name="_setcolor_low"> -->
|
||||
<item><ref id="_sound" name="_sound">
|
||||
<item><ref id="get_ostype" name="get_ostype">
|
||||
<!-- <item><ref id="get_tv" name="get_tv"> -->
|
||||
<item><ref id="get_tv" name="get_tv">
|
||||
</itemize>
|
||||
|
||||
(incomplete)
|
||||
@@ -227,7 +229,7 @@ function.
|
||||
<!-- <item><ref id="cbm_readdir" name="cbm_readdir"> -->
|
||||
<!-- <item><ref id="cbm_save" name="cbm_save"> -->
|
||||
<!-- <item><ref id="cbm_write" name="cbm_write"> -->
|
||||
<!-- <item><ref id="get_tv" name="get_tv"> -->
|
||||
<item><ref id="get_tv" name="get_tv">
|
||||
<item><ref id="kbrepeat" name="kbrepeat">
|
||||
<item><ref id="waitvsync" name="waitvsync">
|
||||
</itemize>
|
||||
@@ -348,7 +350,7 @@ function.
|
||||
<itemize>
|
||||
<!-- <item><ref id="get_numbanks" name="get_numbanks"> -->
|
||||
<item><ref id="get_ostype" name="get_ostype">
|
||||
<!-- <item><ref id="get_tv" name="get_tv"> -->
|
||||
<item><ref id="get_tv" name="get_tv">
|
||||
<!-- <item><ref id="set_tv" name="set_tv"> -->
|
||||
<!-- <item><ref id="vera_layer_enable" name="vera_layer_enable"> -->
|
||||
<!-- <item><ref id="vera_sprites_enable" name="vera_sprites_enable"> -->
|
||||
@@ -443,7 +445,7 @@ see also <tt>testcode/lib/em-test.c</tt> and <tt>samples/multidemo.c</tt>.
|
||||
<sect1><tt/gamate.h/<label id="gamate.h"><p>
|
||||
|
||||
<itemize>
|
||||
<!-- <item><ref id="get_tv" name="get_tv"> -->
|
||||
<item><ref id="get_tv" name="get_tv">
|
||||
<item><ref id="waitvsync" name="waitvsync">
|
||||
</itemize>
|
||||
|
||||
@@ -550,7 +552,7 @@ see also <tt>testcode/lib/em-test.c</tt> and <tt>samples/multidemo.c</tt>.
|
||||
<sect1><tt/nes.h/<label id="nes.h"><p>
|
||||
|
||||
<itemize>
|
||||
<!-- <item><ref id="get_tv" name="get_tv"> -->
|
||||
<item><ref id="get_tv" name="get_tv">
|
||||
<item><ref id="waitvsync" name="waitvsync">
|
||||
</itemize>
|
||||
|
||||
@@ -568,7 +570,7 @@ It does not declare any functions.
|
||||
<sect1><tt/pce.h/<label id="pce.h"><p>
|
||||
|
||||
<itemize>
|
||||
<!-- <item><ref id="get_tv" name="get_tv"> -->
|
||||
<item><ref id="get_tv" name="get_tv">
|
||||
<item><ref id="waitvsync" name="waitvsync">
|
||||
</itemize>
|
||||
|
||||
@@ -4108,6 +4110,31 @@ be used in presence of a prototype.
|
||||
</quote>
|
||||
|
||||
|
||||
<sect1>get_tv<label id="get_tv"><p>
|
||||
|
||||
<quote>
|
||||
<descrip>
|
||||
<tag/Function/The function returns the system's vertical blank frequency.
|
||||
<tag/Header/<tt/<ref id="apple2.h" name="apple2.h">,
|
||||
<ref id="atari.h" name="atari.h">, <ref id="cbm.h" name="cbm.h">,
|
||||
<ref id="cx16.h" name="cx16.h">, <ref id="gamate.h" name="gamate.h">,
|
||||
<ref id="nes.h" name="nes.h">, <ref id="pce.h" name="pce.h">/
|
||||
<tag/Declaration/<tt/unsigned char get_tv (void);/
|
||||
<tag/Description/<tt/get_tv/ is machine dependent and does not exist for
|
||||
all supported targets. If it exists, it returns a number that identifies the
|
||||
frequency at which the screen vertical blank happens (either 50 or 60Hz),
|
||||
if possible.
|
||||
<tag/Notes/<itemize>
|
||||
<item>The function does not exist on all platforms.
|
||||
<item>Return TV_NTSC for 60Hz systems, TV_PAL for 50Hz systems, or
|
||||
TV_OTHER if the scan frequency can not be determined.
|
||||
</itemize>
|
||||
<tag/Availability/cc65 (not all platforms)
|
||||
<tag/Example/None.
|
||||
</descrip>
|
||||
</quote>
|
||||
|
||||
|
||||
<sect1>get_ostype<label id="get_ostype"><p>
|
||||
|
||||
<quote>
|
||||
|
||||
@@ -122,6 +122,11 @@
|
||||
#define APPLE_IIGS1 0x81 /* Apple IIgs (ROM 1) */
|
||||
#define APPLE_IIGS3 0x83 /* Apple IIgs (ROM 3) */
|
||||
|
||||
/* Return codes for get_tv() */
|
||||
#define TV_NTSC 0
|
||||
#define TV_PAL 1
|
||||
#define TV_OTHER 2
|
||||
|
||||
extern unsigned char _dos_type;
|
||||
/* Valid _dos_type values:
|
||||
**
|
||||
@@ -200,6 +205,9 @@ extern void a2_lo_tgi[];
|
||||
void beep (void);
|
||||
/* Beep beep. */
|
||||
|
||||
unsigned char get_tv (void);
|
||||
/* Get the machine vblank frequency. Returns one of the TV_xxx codes. */
|
||||
|
||||
unsigned char get_ostype (void);
|
||||
/* Get the machine type. Returns one of the APPLE_xxx codes. */
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/* cx16.h */
|
||||
/* */
|
||||
/* CX16 system-specific definitions */
|
||||
/* For prerelease 39 */
|
||||
/* For prerelease 43 */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided "as-is", without any expressed or implied */
|
||||
@@ -176,6 +176,11 @@ enum {
|
||||
#define VIDEOMODE_40x15 0x04
|
||||
#define VIDEOMODE_20x30 0x05
|
||||
#define VIDEOMODE_20x15 0x06
|
||||
#define VIDEOMODE_22x23 0x07
|
||||
#define VIDEOMODE_64x50 0x08
|
||||
#define VIDEOMODE_64x25 0x09
|
||||
#define VIDEOMODE_32x50 0x0A
|
||||
#define VIDEOMODE_32x25 0x0B
|
||||
#define VIDEOMODE_80COL VIDEOMODE_80x60
|
||||
#define VIDEOMODE_40COL VIDEOMODE_40x30
|
||||
#define VIDEOMODE_320x240 0x80
|
||||
|
||||
189
libsrc/apple2/get_tv.s
Normal file
189
libsrc/apple2/get_tv.s
Normal file
@@ -0,0 +1,189 @@
|
||||
;
|
||||
; Colin Leroy-Mira <colin@colino.net>, 2025
|
||||
;
|
||||
; unsigned char __fastcall__ get_tv(void)
|
||||
;
|
||||
.export _get_tv
|
||||
|
||||
.import _set_iigs_speed, _get_iigs_speed
|
||||
.import ostype
|
||||
|
||||
.constructor calibrate_tv, 2
|
||||
|
||||
.include "accelerator.inc"
|
||||
.include "apple2.inc"
|
||||
.include "get_tv.inc"
|
||||
|
||||
.segment "ONCE"
|
||||
|
||||
; Cycle wasters
|
||||
waste_72:
|
||||
jsr waste_36
|
||||
waste_36:
|
||||
jsr waste_12
|
||||
waste_24:
|
||||
jsr waste_12
|
||||
waste_12:
|
||||
rts
|
||||
|
||||
.proc calibrate_tv
|
||||
lda ostype
|
||||
bmi iigs
|
||||
cmp #$20
|
||||
bcc iip
|
||||
cmp #$40
|
||||
bcc iie
|
||||
|
||||
iic: jmp calibrate_iic
|
||||
iigs: jmp calibrate_iigs
|
||||
iie: jmp calibrate_iie
|
||||
iip: rts ; Keep TV::OTHER.
|
||||
.endproc
|
||||
|
||||
|
||||
; Magic numbers
|
||||
WASTE_LOOP_CYCLES = 92 ; The wait loop total cycles
|
||||
NTSC_LOOP_COUNT = 17030/WASTE_LOOP_CYCLES ; How many loops expected on NTSC
|
||||
PAL_LOOP_COUNT = 20280/WASTE_LOOP_CYCLES ; How many loops expected on PAL
|
||||
STOP_PTRIG = 16500/WASTE_LOOP_CYCLES ; Stop PTRIG at 16.5ms
|
||||
|
||||
; Carry set at enter: wait for VBL +
|
||||
; Carry clear at enter: wait for VBL -
|
||||
; Increments X every 92 cycles.
|
||||
.proc count_until_vbl_bit
|
||||
lda #$10 ; BPL
|
||||
bcc :+
|
||||
lda #$30 ; BMI
|
||||
: sta sign
|
||||
|
||||
; Wait for VBLsign change with 92 cycles loops.
|
||||
; Hit PTRIG repeatedly so that accelerators will slow down.
|
||||
; But stop hitting PTRIG after 16.5ms cycles, so that on the //c,
|
||||
; the VBLINT will not be reset right before we get it. 16.5ms
|
||||
; is a good value because it's far enough from 17ms for NTSC
|
||||
; models, and close enough to 20.2ms for PAL models that accelerators
|
||||
; will stay slow until there. (5ms usually).
|
||||
|
||||
: cpx #STOP_PTRIG ; 2 - see if we spent 16.5ms already
|
||||
bcs notrig ; 4 / 5 - if so, stop hitting PTRIG
|
||||
sta PTRIG ; 8 - otherwise hit it
|
||||
bcc count ; 11
|
||||
notrig:
|
||||
nop ; 7 - keep cycle count constant when not
|
||||
nop ; 9 - hitting PTRIG
|
||||
nop ; 11
|
||||
count:
|
||||
inx ; 13
|
||||
jsr waste_72 ; 85
|
||||
bit RDVBLBAR ; 89 - Wait for VBL change
|
||||
sign:
|
||||
bpl :- ; 92 - patched with bpl/bmi
|
||||
rts
|
||||
.endproc
|
||||
|
||||
.proc calibrate_iic
|
||||
php
|
||||
sei
|
||||
|
||||
sta IOUDISOFF
|
||||
lda RDVBLMSK
|
||||
pha ; Back up for cleanup
|
||||
|
||||
bit ENVBL
|
||||
bit PTRIG ; Reset VBL interrupt flag
|
||||
: bit RDVBLBAR ; Wait for one VBL
|
||||
bpl :-
|
||||
|
||||
bit PTRIG ; Reset VBL interrupt flag again
|
||||
ldx #$00
|
||||
clc
|
||||
jsr count_until_vbl_bit
|
||||
|
||||
pla ; Cleanup
|
||||
asl
|
||||
bcs :+ ; VBL interrupts were already enabled
|
||||
bit DISVBL
|
||||
: sta IOUDISON ; IIc Tech Ref Man: The firmware normally leaves IOUDIS on.
|
||||
|
||||
plp
|
||||
jmp calibrate_done
|
||||
.endproc
|
||||
|
||||
.proc calibrate_iie
|
||||
: bit RDVBLBAR ; Wait for bit 7 to be off (VBL start)
|
||||
bmi :-
|
||||
: bit RDVBLBAR ; Wait for bit 7 to be on (VBL end)
|
||||
bpl :-
|
||||
|
||||
; Wait and count during a full cycle
|
||||
ldx #$00
|
||||
sec
|
||||
jsr count_until_vbl_bit
|
||||
clc
|
||||
jsr count_until_vbl_bit
|
||||
|
||||
jmp calibrate_done
|
||||
.endproc
|
||||
|
||||
.proc calibrate_iigs
|
||||
; Backup speed and slow down
|
||||
jsr _get_iigs_speed
|
||||
pha
|
||||
lda #SPEED_SLOW
|
||||
jsr _set_iigs_speed
|
||||
|
||||
; The same as IIe, but reverted, because... something?
|
||||
: bit RDVBLBAR ; Wait for bit 7 to be on (VBL start)
|
||||
bpl :-
|
||||
: bit RDVBLBAR ; Wait for bit 7 to be off (VBL end)
|
||||
bmi :-
|
||||
|
||||
; Wait and count during a full cycle
|
||||
ldx #$00
|
||||
clc
|
||||
jsr count_until_vbl_bit
|
||||
sec
|
||||
jsr count_until_vbl_bit
|
||||
|
||||
jsr calibrate_done
|
||||
|
||||
; Restore user speed
|
||||
pla
|
||||
jmp _set_iigs_speed
|
||||
.endproc
|
||||
|
||||
.proc calibrate_done
|
||||
; Consider X +/- 3 to be valid,
|
||||
; anything else is unknown.
|
||||
|
||||
lda #TV::NTSC
|
||||
cpx #NTSC_LOOP_COUNT-3
|
||||
bcc unexpected
|
||||
cpx #NTSC_LOOP_COUNT+3
|
||||
bcc matched
|
||||
|
||||
lda #TV::PAL
|
||||
cpx #PAL_LOOP_COUNT-3
|
||||
bcc unexpected
|
||||
cpx #PAL_LOOP_COUNT+3
|
||||
bcs unexpected
|
||||
|
||||
matched:
|
||||
sta tv
|
||||
|
||||
unexpected:
|
||||
rts
|
||||
.endproc
|
||||
|
||||
.code
|
||||
|
||||
; The only thing remaining from that code after init
|
||||
.proc _get_tv
|
||||
lda tv
|
||||
ldx #>$0000
|
||||
rts
|
||||
.endproc
|
||||
|
||||
.segment "INIT"
|
||||
|
||||
tv: .byte TV::OTHER
|
||||
@@ -147,6 +147,7 @@ icbll_copy:
|
||||
sta dataptr+1
|
||||
lda ICBLL,x
|
||||
sta copylen
|
||||
beq copied ; length = 0 if EOF
|
||||
pha ; remember for return value
|
||||
ldy #0
|
||||
ldx index
|
||||
@@ -159,7 +160,7 @@ copy: lda linebuf,x
|
||||
bne copy
|
||||
|
||||
pla ; length
|
||||
pha ; save length to return at okdone
|
||||
copied: pha ; save length to return at okdone
|
||||
|
||||
clc
|
||||
adc index
|
||||
|
||||
@@ -6,6 +6,60 @@
|
||||
; Almost 7 times faster, uses no RAM (vs 14 bytes BSS), and takes 1/4 the space
|
||||
; vs the official C source.
|
||||
;
|
||||
;
|
||||
; C implementation was:
|
||||
|
||||
; void decompress_lz4 (unsigned char *in, unsigned char *out, const int outlen) {
|
||||
; unsigned char token, tmp;
|
||||
; unsigned int offset;
|
||||
; unsigned char *end = out+outlen;
|
||||
; unsigned char *copysrc;
|
||||
;
|
||||
; while (out < end) {
|
||||
; token = *in++;
|
||||
; offset = token >> 4;
|
||||
;
|
||||
; token &= 0x0f;
|
||||
; token += 4; // Minmatch
|
||||
;
|
||||
; if (offset == 15) {
|
||||
; moreliterals:
|
||||
; tmp = *in++;
|
||||
; offset += tmp;
|
||||
; if (tmp == 255)
|
||||
; goto moreliterals;
|
||||
; }
|
||||
;
|
||||
; if (offset) {
|
||||
; memcpy(out, in, offset);
|
||||
; out += offset;
|
||||
; in += offset;
|
||||
; }
|
||||
;
|
||||
; if (out >= end) {
|
||||
; return;
|
||||
; }
|
||||
;
|
||||
; offset = (*in);
|
||||
; in++;
|
||||
; offset += (*in)<<8;
|
||||
; in++;
|
||||
;
|
||||
; copysrc = out - offset;
|
||||
; offset = token;
|
||||
;
|
||||
; if (token == 19) {
|
||||
; morematches:
|
||||
; tmp = *in++;
|
||||
; offset += tmp;
|
||||
; if (tmp == 255)
|
||||
; goto morematches;
|
||||
; }
|
||||
;
|
||||
; memcpy(out, copysrc, offset);
|
||||
; out += offset;
|
||||
; }
|
||||
; }
|
||||
|
||||
.importzp sp, sreg, regsave, regbank
|
||||
.importzp tmp1, tmp2, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4
|
||||
|
||||
@@ -9,6 +9,13 @@
|
||||
; #define VIDEOMODE_40x15 0x04
|
||||
; #define VIDEOMODE_20x30 0x05
|
||||
; #define VIDEOMODE_20x15 0x06
|
||||
; #define VIDEOMODE_22x23 0x07
|
||||
; #define VIDEOMODE_64x50 0x08
|
||||
; #define VIDEOMODE_64x25 0x09
|
||||
; #define VIDEOMODE_32x50 0x0A
|
||||
; #define VIDEOMODE_32x25 0x0B
|
||||
; #define VIDEOMODE_80COL VIDEOMODE_80x60
|
||||
; #define VIDEOMODE_40COL VIDEOMODE_40x30
|
||||
; #define VIDEOMODE_320x240 0x80
|
||||
; #define VIDEOMODE_SWAP (-1)
|
||||
;
|
||||
|
||||
@@ -92,7 +92,7 @@ static Collection LPStack = STATIC_COLLECTION_INITIALIZER;
|
||||
|
||||
|
||||
|
||||
static Literal* NewLiteral (const void* Buf, unsigned Len)
|
||||
static Literal* NewLiteral (const StrBuf* S)
|
||||
/* Create a new literal and return it */
|
||||
{
|
||||
/* Allocate memory */
|
||||
@@ -103,7 +103,7 @@ static Literal* NewLiteral (const void* Buf, unsigned Len)
|
||||
L->RefCount = 0;
|
||||
L->Output = 0;
|
||||
SB_Init (&L->Data);
|
||||
SB_AppendBuf (&L->Data, Buf, Len);
|
||||
SB_Append (&L->Data, S);
|
||||
|
||||
/* Return the new literal */
|
||||
return L;
|
||||
@@ -162,7 +162,7 @@ void ReleaseLiteral (Literal* L)
|
||||
void TranslateLiteral (Literal* L)
|
||||
/* Translate a literal into the target charset */
|
||||
{
|
||||
TgtTranslateBuf (SB_GetBuf (&L->Data), SB_GetLen (&L->Data));
|
||||
TgtTranslateStrBuf (&L->Data);
|
||||
}
|
||||
|
||||
|
||||
@@ -468,18 +468,18 @@ void OutputGlobalLiteralPool (void)
|
||||
Literal* AddLiteral (const char* S)
|
||||
/* Add a literal string to the literal pool. Return the literal. */
|
||||
{
|
||||
return AddLiteralBuf (S, strlen (S) + 1);
|
||||
StrBuf SB;
|
||||
SB_InitFromString(&SB, S);
|
||||
return AddLiteralStr(&SB);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Literal* AddLiteralBuf (const void* Buf, unsigned Len)
|
||||
/* Add a buffer containing a literal string to the literal pool. Return the
|
||||
** literal.
|
||||
*/
|
||||
Literal* AddLiteralStr (const StrBuf* S)
|
||||
/* Add a literal string to the literal pool. Return the literal. */
|
||||
{
|
||||
/* Create a new literal */
|
||||
Literal* L = NewLiteral (Buf, Len);
|
||||
Literal* L = NewLiteral (S);
|
||||
|
||||
/* Add the literal to the correct pool */
|
||||
if (IS_Get (&WritableStrings)) {
|
||||
@@ -491,11 +491,3 @@ Literal* AddLiteralBuf (const void* Buf, unsigned Len)
|
||||
/* Return the new literal */
|
||||
return L;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Literal* AddLiteralStr (const StrBuf* S)
|
||||
/* Add a literal string to the literal pool. Return the literal. */
|
||||
{
|
||||
return AddLiteralBuf (SB_GetConstBuf (S), SB_GetLen (S));
|
||||
}
|
||||
|
||||
@@ -125,11 +125,6 @@ void OutputGlobalLiteralPool (void);
|
||||
Literal* AddLiteral (const char* S);
|
||||
/* Add a literal string to the literal pool. Return the literal. */
|
||||
|
||||
Literal* AddLiteralBuf (const void* Buf, unsigned Len);
|
||||
/* Add a buffer containing a literal string to the literal pool. Return the
|
||||
** literal.
|
||||
*/
|
||||
|
||||
Literal* AddLiteralStr (const StrBuf* S);
|
||||
/* Add a literal string to the literal pool. Return the literal. */
|
||||
|
||||
|
||||
@@ -2647,8 +2647,9 @@ static void DoDefine (void)
|
||||
** "There shall be white-space between the identifier and the
|
||||
** replacement list in the definition of an object-like macro."
|
||||
** Note: C89 doesn't have this constraint.
|
||||
** Note: if there is no replacement list, a space is not required.
|
||||
*/
|
||||
if (Std == STD_C99 && !IsSpace (CurC)) {
|
||||
if (Std == STD_C99 && !IsSpace (CurC) && CurC != 0) {
|
||||
PPWarning ("ISO C99 requires whitespace after the macro name");
|
||||
}
|
||||
|
||||
|
||||
@@ -163,6 +163,12 @@ static const struct Keyword {
|
||||
typedef uint32_t scan_t;
|
||||
|
||||
|
||||
/* ParseChar return values */
|
||||
typedef struct {
|
||||
int Val;
|
||||
int Cooked;
|
||||
} parsedchar_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
/* code */
|
||||
/*****************************************************************************/
|
||||
@@ -326,13 +332,16 @@ static void SetTok (int tok)
|
||||
|
||||
|
||||
|
||||
static int ParseChar (void)
|
||||
static parsedchar_t ParseChar (void)
|
||||
/* Parse a character token. Converts escape chars into character codes. */
|
||||
{
|
||||
parsedchar_t Result;
|
||||
int C;
|
||||
int HadError;
|
||||
int Count;
|
||||
|
||||
Result.Cooked = 1;
|
||||
|
||||
/* Check for escape chars */
|
||||
if (CurC == '\\') {
|
||||
NextChar ();
|
||||
@@ -346,6 +355,14 @@ static int ParseChar (void)
|
||||
case 'b':
|
||||
C = '\b';
|
||||
break;
|
||||
case 'e':
|
||||
if (IS_Get(&Standard) != STD_CC65) {
|
||||
goto IllegalEscape;
|
||||
}
|
||||
/* we'd like to use \e here, but */
|
||||
/* not all build systems support it */
|
||||
C = '\x1B';
|
||||
break;
|
||||
case 'f':
|
||||
C = '\f';
|
||||
break;
|
||||
@@ -373,6 +390,7 @@ static int ParseChar (void)
|
||||
case 'x':
|
||||
case 'X':
|
||||
/* Hex character constant */
|
||||
Result.Cooked = 0;
|
||||
if (!IsXDigit (NextC)) {
|
||||
Error ("\\x used with no following hex digits");
|
||||
C = ' ';
|
||||
@@ -401,6 +419,7 @@ static int ParseChar (void)
|
||||
case '6':
|
||||
case '7':
|
||||
/* Octal constant */
|
||||
Result.Cooked = 0;
|
||||
Count = 1;
|
||||
C = HexVal (CurC);
|
||||
while (IsODigit (NextC) && Count++ < 3) {
|
||||
@@ -411,6 +430,7 @@ static int ParseChar (void)
|
||||
Error ("Octal character constant out of range");
|
||||
break;
|
||||
default:
|
||||
IllegalEscape:
|
||||
C = CurC;
|
||||
Error ("Illegal escaped character: 0x%02X", CurC);
|
||||
break;
|
||||
@@ -423,7 +443,12 @@ static int ParseChar (void)
|
||||
NextChar ();
|
||||
|
||||
/* Do correct sign extension */
|
||||
return SignExtendChar (C);
|
||||
Result.Val = SignExtendChar(C);
|
||||
if (Result.Cooked) {
|
||||
Result.Cooked = Result.Val;
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
||||
@@ -431,7 +456,7 @@ static int ParseChar (void)
|
||||
static void CharConst (void)
|
||||
/* Parse a character constant token */
|
||||
{
|
||||
int C;
|
||||
parsedchar_t C;
|
||||
|
||||
if (CurC == 'L') {
|
||||
/* Wide character constant */
|
||||
@@ -457,7 +482,8 @@ static void CharConst (void)
|
||||
}
|
||||
|
||||
/* Translate into target charset */
|
||||
NextTok.IVal = SignExtendChar (C);
|
||||
NextTok.IVal = SignExtendChar (C.Val);
|
||||
NextTok.Cooked = C.Cooked;
|
||||
|
||||
/* Character constants have type int */
|
||||
NextTok.Type = type_int;
|
||||
@@ -468,6 +494,9 @@ static void CharConst (void)
|
||||
static void StringConst (void)
|
||||
/* Parse a quoted string token */
|
||||
{
|
||||
/* result from ParseChar */
|
||||
parsedchar_t ParsedChar;
|
||||
|
||||
/* String buffer */
|
||||
StrBuf S = AUTO_STRBUF_INITIALIZER;
|
||||
|
||||
@@ -494,7 +523,8 @@ static void StringConst (void)
|
||||
Error ("Unexpected newline");
|
||||
break;
|
||||
}
|
||||
SB_AppendChar (&S, ParseChar ());
|
||||
ParsedChar = ParseChar ();
|
||||
SB_AppendCharCooked(&S, ParsedChar.Val, ParsedChar.Cooked);
|
||||
}
|
||||
|
||||
/* Skip closing quote char if there was one */
|
||||
@@ -689,6 +719,7 @@ static void NumericConst (void)
|
||||
|
||||
/* Set the value and the token */
|
||||
NextTok.IVal = IVal;
|
||||
NextTok.Cooked = 0;
|
||||
NextTok.Tok = TOK_ICONST;
|
||||
|
||||
} else {
|
||||
@@ -805,7 +836,12 @@ static void GetNextInputToken (void)
|
||||
if (NextTok.Tok == TOK_SCONST || NextTok.Tok == TOK_WCSCONST) {
|
||||
TranslateLiteral (NextTok.SVal);
|
||||
} else if (NextTok.Tok == TOK_CCONST || NextTok.Tok == TOK_WCCONST) {
|
||||
NextTok.IVal = SignExtendChar (TgtTranslateChar (NextTok.IVal));
|
||||
if (NextTok.Cooked) {
|
||||
NextTok.IVal = SignExtendChar (TgtTranslateChar (NextTok.IVal));
|
||||
}
|
||||
else {
|
||||
NextTok.IVal = SignExtendChar (NextTok.IVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -213,6 +213,7 @@ typedef struct Token Token;
|
||||
struct Token {
|
||||
token_t Tok; /* The token itself */
|
||||
long IVal; /* The integer attribute */
|
||||
int Cooked; /* The "cooked" flag for char constants */
|
||||
Double FVal; /* The float attribute */
|
||||
struct Literal* SVal; /* String literal is any */
|
||||
ident Ident; /* Identifier if IDENT */
|
||||
|
||||
@@ -82,6 +82,7 @@ StrBuf* SB_InitFromString (StrBuf* B, const char* S)
|
||||
B->Len = strlen (S);
|
||||
B->Index = 0;
|
||||
B->Buf = (char*) S;
|
||||
B->Cooked = (char*) S;
|
||||
return B;
|
||||
}
|
||||
|
||||
@@ -92,6 +93,7 @@ void SB_Done (StrBuf* B)
|
||||
{
|
||||
if (B->Allocated) {
|
||||
xfree (B->Buf);
|
||||
xfree (B->Cooked);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,10 +148,12 @@ void SB_Realloc (StrBuf* B, unsigned NewSize)
|
||||
*/
|
||||
if (B->Allocated) {
|
||||
/* Just reallocate the block */
|
||||
B->Buf = xrealloc (B->Buf, NewAllocated);
|
||||
B->Buf = xrealloc (B->Buf, NewAllocated);
|
||||
B->Cooked = xrealloc (B->Cooked, NewAllocated);
|
||||
} else {
|
||||
/* Allocate a new block and copy */
|
||||
B->Buf = memcpy (xmalloc (NewAllocated), B->Buf, B->Len);
|
||||
B->Buf = memcpy (xmalloc (NewAllocated), B->Buf, B->Len);
|
||||
B->Cooked = memcpy (xmalloc (NewAllocated), B->Cooked, B->Len);
|
||||
}
|
||||
|
||||
/* Remember the new block size */
|
||||
@@ -178,10 +182,12 @@ static void SB_CheapRealloc (StrBuf* B, unsigned NewSize)
|
||||
/* Free the old buffer if there is one */
|
||||
if (B->Allocated) {
|
||||
xfree (B->Buf);
|
||||
xfree (B->Cooked);
|
||||
}
|
||||
|
||||
/* Allocate a fresh block */
|
||||
B->Buf = xmalloc (NewAllocated);
|
||||
B->Buf = xmalloc (NewAllocated);
|
||||
B->Cooked = xmalloc (NewAllocated);
|
||||
|
||||
/* Remember the new block size */
|
||||
B->Allocated = NewAllocated;
|
||||
@@ -222,6 +228,7 @@ void SB_Terminate (StrBuf* B)
|
||||
SB_Realloc (B, NewLen);
|
||||
}
|
||||
B->Buf[B->Len] = '\0';
|
||||
B->Cooked[B->Len] = '\0';
|
||||
}
|
||||
|
||||
|
||||
@@ -234,6 +241,22 @@ void SB_CopyBuf (StrBuf* Target, const char* Buf, unsigned Size)
|
||||
SB_CheapRealloc (Target, Size);
|
||||
}
|
||||
memcpy (Target->Buf, Buf, Size);
|
||||
memcpy (Target->Cooked, Buf, Size); /* nothing raw */
|
||||
}
|
||||
Target->Len = Size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SB_CopyBufCooked (StrBuf* Target, const char* Buf, const char* Cooked, unsigned Size)
|
||||
/* Copy Buf and Cooked to Target, discarding the old contents of Target */
|
||||
{
|
||||
if (Size) {
|
||||
if (Target->Allocated < Size) {
|
||||
SB_CheapRealloc (Target, Size);
|
||||
}
|
||||
memcpy (Target->Buf, Buf, Size);
|
||||
memcpy (Target->Cooked, Cooked, Size);
|
||||
}
|
||||
Target->Len = Size;
|
||||
}
|
||||
@@ -254,7 +277,7 @@ void SB_CopyStr (StrBuf* Target, const char* S)
|
||||
void SB_Copy (StrBuf* Target, const StrBuf* Source)
|
||||
/* Copy Source to Target, discarding the old contents of Target */
|
||||
{
|
||||
SB_CopyBuf (Target, Source->Buf, Source->Len);
|
||||
SB_CopyBufCooked (Target, Source->Buf, Source->Cooked, Source->Len);
|
||||
Target->Index = Source->Index;
|
||||
}
|
||||
#endif
|
||||
@@ -269,6 +292,21 @@ void SB_AppendChar (StrBuf* B, int C)
|
||||
SB_Realloc (B, NewLen);
|
||||
}
|
||||
B->Buf[B->Len] = (char) C;
|
||||
B->Cooked[B->Len] = (char) C;
|
||||
B->Len = NewLen;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SB_AppendCharCooked (StrBuf* B, int C, int Cooked)
|
||||
/* Append a character to a string buffer */
|
||||
{
|
||||
unsigned NewLen = B->Len + 1;
|
||||
if (NewLen > B->Allocated) {
|
||||
SB_Realloc (B, NewLen);
|
||||
}
|
||||
B->Buf[B->Len] = (char) C;
|
||||
B->Cooked[B->Len] = (char) (Cooked ? C : 0);
|
||||
B->Len = NewLen;
|
||||
}
|
||||
|
||||
@@ -282,6 +320,7 @@ void SB_AppendBuf (StrBuf* B, const char* S, unsigned Size)
|
||||
SB_Realloc (B, NewLen);
|
||||
}
|
||||
memcpy (B->Buf + B->Len, S, Size);
|
||||
memcpy (B->Cooked + B->Len, S, Size);
|
||||
B->Len = NewLen;
|
||||
}
|
||||
|
||||
@@ -301,7 +340,13 @@ void SB_AppendStr (StrBuf* B, const char* S)
|
||||
void SB_Append (StrBuf* Target, const StrBuf* Source)
|
||||
/* Append the contents of Source to Target */
|
||||
{
|
||||
SB_AppendBuf (Target, Source->Buf, Source->Len);
|
||||
unsigned NewLen = Target->Len + Source->Len;
|
||||
if (NewLen > Target->Allocated) {
|
||||
SB_Realloc (Target, NewLen);
|
||||
}
|
||||
memcpy (Target->Buf + Target->Len, Source->Buf, Source->Len);
|
||||
memcpy (Target->Cooked + Target->Len, Source->Cooked, Source->Len);
|
||||
Target->Len = NewLen;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -53,10 +53,17 @@
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
/* We want to track whether a character is "raw" or not. */
|
||||
/* "raw" characters should NOT be translated when translating a string. */
|
||||
/* We do this by keeping a second array parallel to "Buf" called "Cooked". */
|
||||
/* Think of "cooked" as the inverse of "raw". */
|
||||
/* If Cooked[n] is 0, then the character is raw and should not be translated. */
|
||||
/* This was done to keep LIT_STR_BUFFER sane. */
|
||||
|
||||
typedef struct StrBuf StrBuf;
|
||||
struct StrBuf {
|
||||
char* Buf; /* Pointer to buffer */
|
||||
char* Cooked; /* Pointer to cooked buffer */
|
||||
unsigned Len; /* Length of the string */
|
||||
unsigned Index; /* Used for reading (Get and friends) */
|
||||
unsigned Allocated; /* Size of allocated memory */
|
||||
@@ -66,13 +73,13 @@ struct StrBuf {
|
||||
extern const StrBuf EmptyStrBuf;
|
||||
|
||||
/* Initializer for static string bufs */
|
||||
#define STATIC_STRBUF_INITIALIZER { 0, 0, 0, 0 }
|
||||
#define STATIC_STRBUF_INITIALIZER { 0, 0, 0, 0, 0 }
|
||||
|
||||
/* Initializer for auto string bufs */
|
||||
#define AUTO_STRBUF_INITIALIZER { 0, 0, 0, 0 }
|
||||
#define AUTO_STRBUF_INITIALIZER { 0, 0, 0, 0, 0 }
|
||||
|
||||
/* Initialize with a string literal (beware: evaluates str twice!) */
|
||||
#define LIT_STRBUF_INITIALIZER(str) { (char*)str, sizeof(str)-1, 0, 0 }
|
||||
#define LIT_STRBUF_INITIALIZER(str) { (char*)str, (char *)str, sizeof(str)-1, 0, 0 }
|
||||
|
||||
|
||||
|
||||
@@ -164,6 +171,16 @@ INLINE char* SB_GetBuf (StrBuf* B)
|
||||
# define SB_GetBuf(B) (B)->Buf
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE char* SB_GetCooked (StrBuf* B)
|
||||
/* Return a cooked pointer */
|
||||
{
|
||||
return B->Cooked;
|
||||
}
|
||||
#else
|
||||
# define SB_GetCooked(B) (B)->Cooked
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE char SB_At (const StrBuf* B, unsigned Index)
|
||||
/* Get a character from the buffer */
|
||||
@@ -310,6 +327,9 @@ void SB_Terminate (StrBuf* B);
|
||||
void SB_CopyBuf (StrBuf* Target, const char* Buf, unsigned Size);
|
||||
/* Copy Buf to Target, discarding the old contents of Target */
|
||||
|
||||
void SB_CopyBufCooked (StrBuf* Target, const char* Buf, const char *Cooked, unsigned Size);
|
||||
/* Copy Buf and Cooked to Target, discarding the old contents of Target */
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE void SB_CopyStr (StrBuf* Target, const char* S)
|
||||
/* Copy S to Target, discarding the old contents of Target */
|
||||
@@ -325,7 +345,7 @@ void SB_CopyStr (StrBuf* Target, const char* S);
|
||||
INLINE void SB_Copy (StrBuf* Target, const StrBuf* Source)
|
||||
/* Copy Source to Target, discarding the old contents of Target */
|
||||
{
|
||||
SB_CopyBuf (Target, Source->Buf, Source->Len);
|
||||
SB_CopyBufCooked (Target, Source->Buf, Source->Cooked, Source->Len);
|
||||
Target->Index = Source->Index;
|
||||
}
|
||||
#else
|
||||
@@ -336,6 +356,9 @@ void SB_Copy (StrBuf* Target, const StrBuf* Source);
|
||||
void SB_AppendChar (StrBuf* B, int C);
|
||||
/* Append a character to a string buffer */
|
||||
|
||||
void SB_AppendCharCooked (StrBuf* B, int C, int Cooked);
|
||||
/* Append a character to a string buffer, raw if Cooked == 0 */
|
||||
|
||||
void SB_AppendBuf (StrBuf* B, const char* S, unsigned Size);
|
||||
/* Append a character buffer to the end of the string buffer */
|
||||
|
||||
@@ -354,7 +377,13 @@ void SB_AppendStr (StrBuf* B, const char* S);
|
||||
INLINE void SB_Append (StrBuf* Target, const StrBuf* Source)
|
||||
/* Append the contents of Source to Target */
|
||||
{
|
||||
SB_AppendBuf (Target, Source->Buf, Source->Len);
|
||||
unsigned NewLen = Target->Len + Source->Len;
|
||||
if (NewLen > Target->Allocated) {
|
||||
SB_Realloc (Target, NewLen);
|
||||
}
|
||||
memcpy (Target->Buf + Target->Len, Source->Buf, Source->Len);
|
||||
memcpy (Target->Cooked + Target->Len, Source->Cooked, Source->Len);
|
||||
Target->Len = NewLen;
|
||||
}
|
||||
#else
|
||||
void SB_Append (StrBuf* Target, const StrBuf* Source);
|
||||
|
||||
@@ -121,7 +121,19 @@ void TgtTranslateStrBuf (StrBuf* Buf)
|
||||
** system character set.
|
||||
*/
|
||||
{
|
||||
TgtTranslateBuf (SB_GetBuf (Buf), SB_GetLen (Buf));
|
||||
unsigned char* B = (unsigned char*)SB_GetBuf(Buf);
|
||||
unsigned char* Cooked = (unsigned char*)SB_GetCooked(Buf);
|
||||
unsigned Len = SB_GetLen(Buf);
|
||||
|
||||
/* Translate */
|
||||
while (Len--) {
|
||||
if (*Cooked) {
|
||||
*B = Tab[*B];
|
||||
}
|
||||
/* else { *B = *B; } */
|
||||
++B;
|
||||
++Cooked;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -129,7 +141,7 @@ void TgtTranslateStrBuf (StrBuf* Buf)
|
||||
void TgtTranslateSet (unsigned Index, unsigned char C)
|
||||
/* Set the translation code for the given character */
|
||||
{
|
||||
CHECK (Index < sizeof (Tab));
|
||||
CHECK (Index < (sizeof (Tab) / sizeof(Tab[0])));
|
||||
Tab[Index] = C;
|
||||
}
|
||||
|
||||
|
||||
@@ -149,7 +149,7 @@ unsigned GetGranularity (attr_t Style)
|
||||
|
||||
case atSkip:
|
||||
default:
|
||||
Internal ("GetGraularity called for style = %d", Style);
|
||||
Internal ("GetGranularity called for style = %d", Style);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ endif
|
||||
|
||||
WORKDIR = ../testwrk
|
||||
|
||||
.PHONY: test continue mostlyclean clean
|
||||
.PHONY: test continue mostlyclean clean success_message
|
||||
|
||||
test:
|
||||
@$(MAKE) mostlyclean
|
||||
@@ -25,8 +25,15 @@ continue:
|
||||
@$(MAKE) -C ref all
|
||||
@$(MAKE) -C err all
|
||||
@$(MAKE) -C standard all
|
||||
@$(MAKE) -C standard_err all
|
||||
@$(MAKE) -C misc all
|
||||
@$(MAKE) -C todo all
|
||||
@$(MAKE) success_message
|
||||
|
||||
success_message:
|
||||
$(info ###################################)
|
||||
$(info ### validation suite successful ###)
|
||||
$(info ###################################)
|
||||
|
||||
mostlyclean:
|
||||
@$(MAKE) -C asm clean
|
||||
@@ -35,6 +42,7 @@ mostlyclean:
|
||||
@$(MAKE) -C ref clean
|
||||
@$(MAKE) -C err clean
|
||||
@$(MAKE) -C standard clean
|
||||
@$(MAKE) -C standard_err clean
|
||||
@$(MAKE) -C misc clean
|
||||
@$(MAKE) -C todo clean
|
||||
|
||||
|
||||
@@ -110,6 +110,12 @@ $(WORKDIR)/bug2515.$1.$2.prg: bug2515.c | $(WORKDIR)
|
||||
$(NOT) $(CC65) -t sim$2 -$1 -o $$(@:.prg=.s) $$< 2>$(WORKDIR)/bug2515.$1.$2.out
|
||||
$(ISEQUAL) $(WORKDIR)/bug2515.$1.$2.out bug2515.ref
|
||||
|
||||
# should not issue any warnings in C99 mode
|
||||
$(WORKDIR)/bug2637.$1.$2.prg: bug2637.c | $(WORKDIR)
|
||||
$(if $(QUIET),echo misc/bug2637.$1.$2.prg)
|
||||
$(CC65) --standard c99 -t sim$2 -$1 -o $$(@:.prg=.s) $$< 2>$(WORKDIR)/bug2637.$1.$2.out
|
||||
$(ISEQUAL) $(WORKDIR)/bug2637.$1.$2.out bug2637.ref
|
||||
|
||||
# this one requires -Werror
|
||||
$(WORKDIR)/bug1768.$1.$2.prg: bug1768.c | $(WORKDIR)
|
||||
$(if $(QUIET),echo misc/bug1768.$1.$2.prg)
|
||||
|
||||
15
test/misc/bug2637.c
Normal file
15
test/misc/bug2637.c
Normal file
@@ -0,0 +1,15 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// compile with --standard c99
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
0
test/misc/bug2637.ref
Normal file
0
test/misc/bug2637.ref
Normal file
@@ -12,6 +12,8 @@ compiler is working as expected (when the tests behave as described):
|
||||
/val - The bulk of tests are contained here, individual tests should exit with
|
||||
an exit code of EXIT_SUCCESS when they pass, or EXIT_FAILURE on error.
|
||||
|
||||
/err - contains tests that MUST NOT compile
|
||||
|
||||
/standard - like the tests in /val, the tests must exit with EXIT_SUCCESS on
|
||||
success. Unlike the tests in /val these are not compiled for every
|
||||
combination of optimizer options, but instead always with -Osir and then
|
||||
@@ -19,6 +21,10 @@ compiler is working as expected (when the tests behave as described):
|
||||
to check for regressions in standard conformance of the compiler and the
|
||||
library.
|
||||
|
||||
/standard_err - like the tests in /err, these tests MUST NOT compile, and like
|
||||
the tests in /standard, these are compiled -Osir and then for each
|
||||
supported C-Standard.
|
||||
|
||||
/ref - These tests produce output that must be compared with reference output.
|
||||
Normally the reference output is produced by compiling the program on the
|
||||
host (using gcc mostly) and then running them on the host. Tests should
|
||||
@@ -43,8 +49,6 @@ compiler is working as expected (when the tests behave as described):
|
||||
only ever use this as a last resort when something can not be tested by
|
||||
other means.
|
||||
|
||||
/err - contains tests that MUST NOT compile
|
||||
|
||||
|
||||
/todo and /misc generally contain the tests that fail because of known bugs:
|
||||
|
||||
|
||||
14
test/standard/issue2607_cc65.c
Normal file
14
test/standard/issue2607_cc65.c
Normal file
@@ -0,0 +1,14 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* this should succeed on all three standards
|
||||
* yet use only \e on CC65
|
||||
*/
|
||||
int main(void) {
|
||||
|
||||
#if __CC65_STD__ == __CC65_STD_CC65__
|
||||
printf("\e");
|
||||
#endif
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
55
test/standard_err/Makefile
Normal file
55
test/standard_err/Makefile
Normal file
@@ -0,0 +1,55 @@
|
||||
# Makefile for the tests that MUST NOT compile
|
||||
|
||||
ifneq ($(shell echo),)
|
||||
CMD_EXE = 1
|
||||
endif
|
||||
|
||||
ifdef CMD_EXE
|
||||
S = $(subst /,\,/)
|
||||
NOT = - # Hack
|
||||
NULLDEV = nul:
|
||||
MKDIR = mkdir $(subst /,\,$1)
|
||||
RMDIR = -rmdir /s /q $(subst /,\,$1)
|
||||
else
|
||||
S = /
|
||||
NOT = !
|
||||
NULLDEV = /dev/null
|
||||
MKDIR = mkdir -p $1
|
||||
RMDIR = $(RM) -r $1
|
||||
endif
|
||||
|
||||
ifdef QUIET
|
||||
.SILENT:
|
||||
NULLERR = 2>$(NULLDEV)
|
||||
endif
|
||||
|
||||
CC65 := $(if $(wildcard ../../bin/cc65*),..$S..$Sbin$Scc65,cc65)
|
||||
|
||||
WORKDIR = ../../testwrk/standard_err
|
||||
|
||||
OPTIONS = c89 c99 cc65
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
SOURCES := $(wildcard *.c)
|
||||
TESTS = $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).6502.prg))
|
||||
|
||||
all: $(TESTS)
|
||||
|
||||
$(WORKDIR):
|
||||
$(call MKDIR,$(WORKDIR))
|
||||
|
||||
define PRG_template
|
||||
|
||||
$(WORKDIR)/%.$1.$2.prg: %.c | $(WORKDIR)
|
||||
$(if $(QUIET),echo standard_err/$$*.$1.$2.prg)
|
||||
$(NOT) $(CC65) -t sim$2 $$(CC65FLAGS) -Osir --add-source --standard $1 -o $$(@:.prg=.s) $$< $(NULLERR)
|
||||
|
||||
endef # PRG_template
|
||||
|
||||
$(foreach option,$(OPTIONS),$(eval $(call PRG_template,$(option),6502)))
|
||||
|
||||
#$(foreach option,$(OPTIONS),$(eval $(call PRG_template,$(option),65c02)))
|
||||
|
||||
clean:
|
||||
@$(call RMDIR,$(WORKDIR))
|
||||
14
test/standard_err/issue2607_not_cc65.c
Normal file
14
test/standard_err/issue2607_not_cc65.c
Normal file
@@ -0,0 +1,14 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* this should fail on all three standards
|
||||
*/
|
||||
int main(void) {
|
||||
|
||||
#if __CC65_STD__ != __CC65_STD_CC65__
|
||||
printf("\e");
|
||||
#else
|
||||
#error "this needs to error on CC65 to make it through validation"
|
||||
#endif
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
72
test/val/bug2609.c
Normal file
72
test/val/bug2609.c
Normal file
@@ -0,0 +1,72 @@
|
||||
/* Bug #2609 - charmap translation violates C specification 6.4.4.4 Character constant */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#pragma charmap (0x07, 0x62) /* map \a to b */
|
||||
static_assert('\a' == 0x62);
|
||||
static_assert('\07' == 0x07);
|
||||
static_assert('\x07' == 0x07);
|
||||
|
||||
#pragma charmap (0x07, 0x63) /* map \a to c */
|
||||
static_assert('\a' == 0x63);
|
||||
static_assert('\07' == 0x07);
|
||||
static_assert('\x07' == 0x07);
|
||||
|
||||
#pragma charmap (0x07, 0x07) /* map \a back to x07 */
|
||||
static_assert('\a' == 0x07);
|
||||
static_assert('\07' == 0x07);
|
||||
static_assert('\x07' == 0x07);
|
||||
|
||||
#pragma charmap (0x07, 0x61) /* map \a to a */
|
||||
|
||||
char *s = "\07\a\x07";
|
||||
char t[] = { 7, 0x61, 7, 0 };
|
||||
|
||||
static_assert('\a' == 0x61);
|
||||
static_assert('\07' == 0x07);
|
||||
static_assert('\x07' == 0x07);
|
||||
|
||||
char c_back_a = '\a';
|
||||
char c_hex_07 = '\x07';
|
||||
char c_oct_07 = '\07';
|
||||
int i_back_a = '\a';
|
||||
int i_hex_07 = '\x07';
|
||||
int i_oct_07 = '\07';
|
||||
|
||||
#define TEST(a,b) \
|
||||
if (a != b) { printf("\n\n !FAIL! %s = %04x not %04x\n\n", #a, a, b); return EXIT_FAILURE; }
|
||||
|
||||
int main (void) {
|
||||
int i;
|
||||
|
||||
TEST(c_back_a, 0x61)
|
||||
TEST(c_hex_07, 0x07)
|
||||
TEST(c_oct_07, 07)
|
||||
|
||||
TEST(i_back_a, 0x61)
|
||||
TEST(i_hex_07, 0x07)
|
||||
TEST(i_oct_07, 07)
|
||||
|
||||
assert('\a' == 0x61);
|
||||
assert('\07' == 0x07);
|
||||
assert('\x07' == 0x07);
|
||||
|
||||
if (strcmp(s,t) || s[0] == s[1]) {
|
||||
printf("\n\n !FAIL! strcmp\n");
|
||||
for (i = 0; i < 4; i++) {
|
||||
printf("%02x ", s[i]);
|
||||
}
|
||||
printf("\n");
|
||||
for (i = 0; i < 4; i++) {
|
||||
printf("%02x ", t[i]);
|
||||
}
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
15
test/val/bug2610.c
Normal file
15
test/val/bug2610.c
Normal file
@@ -0,0 +1,15 @@
|
||||
#include <stdio.h>
|
||||
#if '\x0A' != 0x0A
|
||||
#error "Suspicious character set translation"
|
||||
#endif
|
||||
int main()
|
||||
{
|
||||
char c = '\x0A';
|
||||
if (c == 0x0A) {
|
||||
printf("Ok\n");
|
||||
return 0;
|
||||
} else {
|
||||
printf("Failed\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user