mirror of
https://github.com/cc65/cc65.git
synced 2024-12-23 04:30:10 +00:00
267 lines
8.4 KiB
C
267 lines
8.4 KiB
C
/*
|
|
!!DESCRIPTION!! C-Manual Chapter 2.43: character constants
|
|
!!ORIGIN!! LCC 4.1 Testsuite
|
|
!!LICENCE!! own, freely distributeable for non-profit. read CPYRIGHT.LCC
|
|
*/
|
|
|
|
#include "common.h"
|
|
|
|
struct defs {
|
|
int cbits; /* No. of bits per char */
|
|
int ibits; /* int */
|
|
int sbits; /* short */
|
|
int lbits; /* long */
|
|
int ubits; /* unsigned */
|
|
int fbits; /* float */
|
|
int dbits; /* double */
|
|
#ifndef NO_FLOATS
|
|
float fprec; /* Smallest number that can be */
|
|
float dprec; /* significantly added to 1. */
|
|
#endif
|
|
int flgs; /* Print return codes, by section */
|
|
int flgm; /* Announce machine dependencies */
|
|
int flgd; /* give explicit diagnostics */
|
|
int flgl; /* Report local return codes. */
|
|
int rrc; /* recent return code */
|
|
int crc; /* Cumulative return code */
|
|
char rfs[8]; /* Return from section */
|
|
};
|
|
|
|
int lbits; /* long */
|
|
int ubits; /* unsigned */
|
|
int fbits; /* float */
|
|
int dbits; /* double */
|
|
#ifndef NO_FLOATS
|
|
float fprec; /* Smallest number that can be */
|
|
float dprec; /* significantly added to 1. */
|
|
#endif
|
|
int flgs; /* Print return codes, by section */
|
|
int flgm; /* Announce machine dependencies */
|
|
int flgd; /* give explicit diagnostics */
|
|
int flgl; /* Report local return codes. */
|
|
int rrc; /* recent return code */
|
|
int crc; /* Cumulative return code */
|
|
char rfs[8]; /* Return from section */
|
|
|
|
/*********************************************************************************************
|
|
2.4.3 Character constants
|
|
**********************************************************************************************/
|
|
|
|
#ifndef NO_OLD_FUNC_DECL
|
|
zerofill(x)
|
|
char *x;
|
|
{
|
|
#else
|
|
void zerofill(char *x) {
|
|
#endif
|
|
int j;
|
|
|
|
for (j=0; j<256; j++) *x++ = 0;
|
|
}
|
|
|
|
#ifndef NO_OLD_FUNC_DECL
|
|
sumof(x)
|
|
char *x;
|
|
{
|
|
#else
|
|
int sumof(char *x) {
|
|
#endif
|
|
char *p;
|
|
int total, j;
|
|
|
|
p = x;
|
|
total = 0;
|
|
|
|
for(j=0; j<256; j++) total = total+ *p++;
|
|
return total;
|
|
}
|
|
|
|
char chars[256];
|
|
|
|
#ifndef NO_OLD_FUNC_DECL
|
|
s243(pd0)
|
|
struct defs *pd0;
|
|
{
|
|
#else
|
|
int s243(struct defs *pd0) {
|
|
#endif
|
|
static char s243er[] = "s243,er%d\n";
|
|
static char qs243[8] = "s243 ";
|
|
char *ps, *pt;
|
|
int rc;
|
|
/* char chars[256]; */
|
|
|
|
rc = 0;
|
|
ps = qs243;
|
|
pt = pd0->rfs;
|
|
while(*pt++ = *ps++);
|
|
|
|
/* One of the problems that arises when testing character constants
|
|
is that of definition: What, exactly, is the character set?
|
|
In order to guarantee a certain amount of machine independence,
|
|
the character set we will use here is the set of characters writ-
|
|
able as escape sequences in C, plus those characters used in writ-
|
|
ing C programs, i.e.,
|
|
|
|
letters:
|
|
ABCDEFGHIJKLMNOPQRSTUVWXYZ 26
|
|
abcdefghijklmnopqrstuvwxyz 26
|
|
numbers:
|
|
0123456789 10
|
|
special characters:
|
|
~!"#%&()_=-^|{}[]+;*:<>,.?/ 27
|
|
extra special characters:
|
|
newline \n
|
|
horizontal tab \t
|
|
backspace \b
|
|
carriage return \r
|
|
form feed \f
|
|
backslash \\
|
|
single quote \' 7
|
|
blank & NUL 2
|
|
---
|
|
98
|
|
|
|
Any specific implementation of C may of course support additional
|
|
characters. */
|
|
|
|
/* Since the value of a character constant is the numerical value
|
|
of the character in the machine's character set, there should
|
|
be a one-to-one correspondence between characters and values. */
|
|
|
|
zerofill(chars);
|
|
|
|
chars['a'] = 1; chars['A'] = 1; chars['~'] = 1; chars['0'] = 1;
|
|
chars['b'] = 1; chars['B'] = 1; chars['!'] = 1; chars['1'] = 1;
|
|
chars['c'] = 1; chars['C'] = 1; chars['"'] = 1; chars['2'] = 1;
|
|
chars['d'] = 1; chars['D'] = 1; chars['#'] = 1; chars['3'] = 1;
|
|
chars['e'] = 1; chars['E'] = 1; chars['%'] = 1; chars['4'] = 1;
|
|
chars['f'] = 1; chars['F'] = 1; chars['&'] = 1; chars['5'] = 1;
|
|
chars['g'] = 1; chars['G'] = 1; chars['('] = 1; chars['6'] = 1;
|
|
chars['h'] = 1; chars['H'] = 1; chars[')'] = 1; chars['7'] = 1;
|
|
chars['i'] = 1; chars['I'] = 1; chars['_'] = 1; chars['8'] = 1;
|
|
chars['j'] = 1; chars['J'] = 1; chars['='] = 1; chars['9'] = 1;
|
|
chars['k'] = 1; chars['K'] = 1; chars['-'] = 1;
|
|
chars['l'] = 1; chars['L'] = 1; chars['^'] = 1;
|
|
chars['m'] = 1; chars['M'] = 1; chars['|'] = 1; chars['\n'] = 1;
|
|
chars['n'] = 1; chars['N'] = 1; chars['\t'] = 1;
|
|
chars['o'] = 1; chars['O'] = 1; chars['{'] = 1; chars['\b'] = 1;
|
|
chars['p'] = 1; chars['P'] = 1; chars['}'] = 1; chars['\r'] = 1;
|
|
chars['q'] = 1; chars['Q'] = 1; chars['['] = 1; chars['\f'] = 1;
|
|
chars['r'] = 1; chars['R'] = 1; chars[']'] = 1;
|
|
chars['s'] = 1; chars['S'] = 1; chars['+'] = 1; chars['\\'] = 1;
|
|
chars['t'] = 1; chars['T'] = 1; chars[';'] = 1; chars['\''] = 1;
|
|
chars['u'] = 1; chars['U'] = 1; chars['*'] = 1;
|
|
chars['v'] = 1; chars['V'] = 1; chars[':'] = 1; chars['\0'] = 1;
|
|
chars['w'] = 1; chars['W'] = 1; chars['<'] = 1; chars[' '] = 1;
|
|
chars['x'] = 1; chars['X'] = 1; chars['>'] = 1;
|
|
chars['y'] = 1; chars['Y'] = 1; chars[','] = 1;
|
|
chars['z'] = 1; chars['Z'] = 1; chars['.'] = 1;
|
|
chars['?'] = 1;
|
|
chars['/'] = 1;
|
|
|
|
if(sumof(chars) != 98){
|
|
rc = rc+1;
|
|
if(pd0->flgd != 0) printf(s243er,1);
|
|
}
|
|
|
|
#ifndef NO_BACKSLASH_CHARCODE
|
|
|
|
/* Finally, the escape \ddd consists of the backslash followed
|
|
by 1, 2, or 3 octal digits which are taken to specify the
|
|
desired character. */
|
|
|
|
/*
|
|
this test is non portable and inaccurate, we replace it
|
|
by a more failproof version
|
|
|
|
if(
|
|
'\0' != 0 ||
|
|
'\01' != 1 ||
|
|
'\02' != 2 ||
|
|
'\03' != 3 ||
|
|
'\04' != 4 ||
|
|
'\05' != 5 ||
|
|
'\06' != 6 ||
|
|
'\07' != 7 ||
|
|
'\10' != 8 ||
|
|
'\17' != 15 ||
|
|
'\20' != 16 ||
|
|
'\77' != 63 ||
|
|
'\100' != 64 ||
|
|
'\177' != 127
|
|
)
|
|
*/
|
|
if(
|
|
('0' != '\60') ||
|
|
('9' != '\71') ||
|
|
('A' != '\101') ||
|
|
('Z' != '\132') ||
|
|
('a' != '\141') ||
|
|
('z' != '\172')
|
|
)
|
|
|
|
{
|
|
rc = rc+8;
|
|
if(pd0->flgd != 0)
|
|
{
|
|
printf(s243er,8);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*********************************************************************************************
|
|
the main loop that launches the sections
|
|
*********************************************************************************************/
|
|
|
|
#define cq_sections 1
|
|
|
|
#ifndef NO_TYPELESS_STRUCT_PTR
|
|
int section(int j,struct* pd0){
|
|
#else
|
|
int section(int j,void* pd0){
|
|
#endif
|
|
switch(j){
|
|
case 0: return s243(pd0);
|
|
}
|
|
}
|
|
|
|
/*
|
|
C REFERENCE MANUAL (main)
|
|
*/
|
|
|
|
#ifndef NO_OLD_FUNC_DECL
|
|
main(n,args)
|
|
int n;
|
|
char **args;
|
|
{
|
|
#else
|
|
int main(int n,char **args) {
|
|
#endif
|
|
|
|
int j;
|
|
static struct defs d0, *pd0;
|
|
|
|
d0.flgs = 1; /* These flags dictate */
|
|
d0.flgm = 1; /* the verbosity of */
|
|
d0.flgd = 1; /* the program. */
|
|
d0.flgl = 1;
|
|
|
|
pd0 = &d0;
|
|
|
|
for (j=0; j<cq_sections; j++) {
|
|
d0.rrc=section(j,pd0);
|
|
d0.crc=d0.crc+d0.rrc;
|
|
if(d0.flgs != 0) printf("Section %s returned %d.\n",d0.rfs,d0.rrc);
|
|
}
|
|
|
|
if(d0.crc == 0) printf("\nNo errors detected.\n");
|
|
else printf("\nFailed.\n");
|
|
|
|
return d0.crc;
|
|
}
|