diff --git a/programs/develop/ktcc/trunk/libc/include/assert.h b/programs/develop/ktcc/trunk/libc/include/assert.h new file mode 100644 index 0000000000..56c0e97f78 --- /dev/null +++ b/programs/develop/ktcc/trunk/libc/include/assert.h @@ -0,0 +1,18 @@ +#ifndef __ASSERT_H + +#ifdef NDEBUG +# define assert(a) (void)0 +#else +# define assert(a) ((a) ? (void)0 : __assert_func (__FILE__, __LINE__, #a)) +#endif + +#ifdef NDEBUG +# define TRACE(s) void(0) +#else +# define TRACE(s) (__trace_func (__FILE__, __LINE__, #s)) +#endif + +void __assert_func(char*,int,char*); +void __trace_func(char*,int,char*); + +#endif \ No newline at end of file diff --git a/programs/develop/ktcc/trunk/libc/include/ctype.h b/programs/develop/ktcc/trunk/libc/include/ctype.h index 4c0362c67a..19cf75ba41 100644 --- a/programs/develop/ktcc/trunk/libc/include/ctype.h +++ b/programs/develop/ktcc/trunk/libc/include/ctype.h @@ -33,3 +33,5 @@ extern unsigned short __is[128]; #define isascii(c) (!((c)&(~0x7f))) #define toascii(c) ((c)&0x7f) +extern unsigned char tolower(unsigned char c); +extern unsigned char toupper(unsigned char c); diff --git a/programs/develop/ktcc/trunk/libc/include/float.h b/programs/develop/ktcc/trunk/libc/include/float.h index f16f1f0cb5..a2b4ed26a0 100644 --- a/programs/develop/ktcc/trunk/libc/include/float.h +++ b/programs/develop/ktcc/trunk/libc/include/float.h @@ -54,4 +54,12 @@ #endif +#ifndef NAN +# define NAN (__nan__) +#endif + +#ifndef INFINITY +# define INFINITY (__inf__) +#endif + #endif /* _FLOAT_H_ */ diff --git a/programs/develop/ktcc/trunk/libc/include/math.h b/programs/develop/ktcc/trunk/libc/include/math.h index bdf37d7d64..5e7d69e5c7 100644 --- a/programs/develop/ktcc/trunk/libc/include/math.h +++ b/programs/develop/ktcc/trunk/libc/include/math.h @@ -166,6 +166,13 @@ extern float lgammaf_r(float, int *); double round (double x); long double roundl (long double x); +#ifndef NAN +# define NAN (__nan__) +#endif + +#ifndef INFINITY +# define INFINITY (__inf__) +#endif //#endif /* !_POSIX_SOURCE */ diff --git a/programs/develop/ktcc/trunk/libc/include/stdio.h b/programs/develop/ktcc/trunk/libc/include/stdio.h index 62923dceae..f931007d8b 100644 --- a/programs/develop/ktcc/trunk/libc/include/stdio.h +++ b/programs/develop/ktcc/trunk/libc/include/stdio.h @@ -14,13 +14,16 @@ typedef char *va_list; # define NULL ((void*)0) #endif +typedef unsigned int fpos_t; // 32bit is not enough! 4Gb limit +typedef unsigned int size_t; + int format_print(char *dest, size_t maxlen,const char *fmt0, va_list argp); typedef struct { char* buffer; dword buffersize; - dword filesize; - dword filepos; + dword filesize; // too small + dword filepos; // too small char* filename; int mode; } FILE; @@ -33,10 +36,12 @@ typedef struct { #define FILE_OPEN_APPEND 2 #define FILE_OPEN_TEXT 4 #define FILE_OPEN_PLUS 8 -#define EOF -1 +#define EOF (-1) +#define BUFSIZ (256) +#define FILENAME_MAX (0x400) extern FILE* fopen(const char* filename, const char *mode); -extern void fclose(FILE* file); +extern int fclose(FILE* file); extern int feof(FILE* file); extern int fflush(FILE* file); extern int fgetc(FILE* file); @@ -62,6 +67,7 @@ extern int cdecl snprintf(char *dest, size_t size, const char *format,...); extern int cdecl sprintf(char *dest,const char *format,...); #define getc(a) fgetc(a) +#define putc(a, b) fputc(a, b) char * fgets (char * str, int num, FILE * stream); int putchar (int ch); int getchar (void); @@ -76,7 +82,29 @@ int scanf ( const char * format, ...); int vsscanf ( const char * s, const char * format, va_list arg ); int sscanf ( const char * s, const char * format, ...); int vfscanf ( FILE * stream, const char * format, va_list arg ); +int fputs ( const char * str, FILE * file ); +void clearerr ( FILE * stream ); +int ferror ( FILE * stream ); +void perror ( const char * str ); +int vprintf ( const char * format, va_list arg ); +int vsprintf (char * s, const char * format, va_list arg ); +int vfprintf ( FILE * stream, const char * format, va_list arg ); - +extern int errno; +/* errors codes from KOS, but minus */ +#define E_SUCCESS (0) +#define E_UNSUPPORTED (-2) +#define E_UNKNOWNFS (-3) +#define E_NOTFOUND (-5) +#define E_EOF (-6) +#define E_INVALIDPTR (-7) +#define E_DISKFULL (-8) +#define E_FSYSERROR (-9) +#define E_ACCESS (-10) +#define E_HARDWARE (-11) +#define E_NOMEM (-12) +/* conversion errors */ +#define ERANGE (-20) +#define EINVAL (-21) #endif diff --git a/programs/develop/ktcc/trunk/libc/include/stdlib.h b/programs/develop/ktcc/trunk/libc/include/stdlib.h index a474733a10..79719f1bfe 100644 --- a/programs/develop/ktcc/trunk/libc/include/stdlib.h +++ b/programs/develop/ktcc/trunk/libc/include/stdlib.h @@ -3,14 +3,15 @@ #include "kolibrisys.h" #define RAND_MAX 65535 +#ifndef NULL +# define NULL ((void*)0) +#endif -//#define isspace(c) ((c)==' ') #define abs(i) (((i)<0)?(-(i)):(i)) +#define labs(li) abs(li) extern int atoib(char *s,int b); extern int atoi(char *s); -extern unsigned char tolower(unsigned char c); -extern unsigned char toupper(unsigned char c); extern char *itoab(int n,char* s,int b); extern char *itoa(int n,char* s); @@ -25,6 +26,20 @@ double strtod (const char* str, char** endptr); long double strtold (const char* str, char** endptr); float strtof (const char* str, char** endptr); +void* calloc (size_t num, size_t size); #define exit(a) _ksys_exit() -#endif \ No newline at end of file +#define abort() exit(-1) + +typedef struct { + int quot; + int rem; +} div_t; + +typedef div_t ldiv_t; + +div_t div (int numer, int denom); +#define ldiv(a, b) div(a, b) +#define atol(a) atoi(a) + +#endif diff --git a/programs/develop/ktcc/trunk/libc/include/string.h b/programs/develop/ktcc/trunk/libc/include/string.h index cf50c5872d..f69a8036f7 100644 --- a/programs/develop/ktcc/trunk/libc/include/string.h +++ b/programs/develop/ktcc/trunk/libc/include/string.h @@ -1,26 +1,35 @@ #ifndef string_h #define string_h -extern void* memchr(const void*,int,int); -extern int memcmp(const void*,const void*,int); -extern void* memcpy(void*,const void*,int); -extern void* memmove(void*,const void*,int); -extern void* memset(void*,int,int); +typedef unsigned int size_t; + + +extern void* memchr(const void*,int,size_t); +extern int memcmp(const void*,const void*,size_t); +extern void* memcpy(void*,const void*,size_t); +extern void* memmove(void*,const void*,size_t); +extern void* memset(void*,int,size_t); extern char* strcat(char*,const char*); extern char* strchr(const char*,int); extern int strcmp(const char*,const char*); extern int strcoll(const char*,const char*); extern char* strcpy(char*,const char*); -extern int strcspn(const char*,const char*); +extern size_t strcspn(const char*,const char*); extern int strlen(const char*); -extern char* strncat(char*,const char*,int); -extern int strncmp(const char*,const char*,int); -extern char* strncpy(char*,const char*,int); +extern char* strncat(char*,const char*,size_t); +extern int strncmp(const char*,const char*,size_t); +extern char* strncpy(char*,const char*,size_t); extern char* strpbrk(const char*,const char*); extern char* strrchr(const char*,int); -extern int strspn(const char*,const char*); +extern size_t strspn(const char*,const char*); extern char* strstr(const char*,const char*); extern char* strtok(char*,const char*); extern int strxfrm(char*,const char*,int); extern char* strdup(const char*); extern char* strrev(char *p); +char * strerror ( int errnum ); + +#ifndef NULL +# define NULL ((void*)0) +#endif + #endif diff --git a/programs/develop/ktcc/trunk/libc/memory/memalloc.asm b/programs/develop/ktcc/trunk/libc/memory/memalloc.asm index ee64ef9d46..32de642484 100644 --- a/programs/develop/ktcc/trunk/libc/memory/memalloc.asm +++ b/programs/develop/ktcc/trunk/libc/memory/memalloc.asm @@ -8,31 +8,31 @@ public realloc align 4 malloc: - + push ebx mov eax,68 mov ebx,12 - mov ecx,[esp+4] ;size + mov ecx,[esp+8] ;size int 0x40 - + pop ebx ret 4 align 4 free: - + push ebx mov eax,68 mov ebx,13 - mov ecx,[esp+4] + mov ecx,[esp+8] int 0x40 - + pop ebx ret 4 align 4 realloc: - + push ebx mov ebx,20 mov eax,68 - mov edx,[esp+4] ; pointer - mov ecx,[esp+8] ; size + mov edx,[esp+8] ; pointer + mov ecx,[esp+12] ; size int 0x40 - + pop ebx ret 8 diff --git a/programs/develop/ktcc/trunk/libc/stdio/clearerr.c b/programs/develop/ktcc/trunk/libc/stdio/clearerr.c new file mode 100644 index 0000000000..7f0e8a0106 --- /dev/null +++ b/programs/develop/ktcc/trunk/libc/stdio/clearerr.c @@ -0,0 +1,22 @@ +#include +#include + +void clearerr ( FILE * stream ) +{ + errno = 0; +} + +int ferror ( FILE * stream ) +{ + return errno; +} + +void perror ( const char * str ) +{ + char *msg = strerror(errno); + + if (str) + fprintf(stderr, "%s:%s\n", str, msg); + else + fprintf(stderr, "%s\n", msg); +} diff --git a/programs/develop/ktcc/trunk/libc/stdio/fclose.c b/programs/develop/ktcc/trunk/libc/stdio/fclose.c index b0324a7593..2127022051 100644 --- a/programs/develop/ktcc/trunk/libc/stdio/fclose.c +++ b/programs/develop/ktcc/trunk/libc/stdio/fclose.c @@ -2,8 +2,17 @@ #include #include -void fclose(FILE* file) +int fclose(FILE* file) { - free(file->buffer); + if(!file) + { + errno = E_INVALIDPTR; + return EOF; + } + + if(file->buffer) + free(file->buffer); free(file); -} \ No newline at end of file + + return 0; +} diff --git a/programs/develop/ktcc/trunk/libc/stdio/feof.c b/programs/develop/ktcc/trunk/libc/stdio/feof.c index 76f131d55f..f74639ddc3 100644 --- a/programs/develop/ktcc/trunk/libc/stdio/feof.c +++ b/programs/develop/ktcc/trunk/libc/stdio/feof.c @@ -1,5 +1,11 @@ #include int feof(FILE* file) { - return file->filepos>=file->filesize; -} \ No newline at end of file + if(!file) + { + errno = E_INVALIDPTR; + return EOF; + } + + return file->filepos>=file->filesize; +} diff --git a/programs/develop/ktcc/trunk/libc/stdio/fflush.c b/programs/develop/ktcc/trunk/libc/stdio/fflush.c index 1cd7bf355c..24f8d7d2fa 100644 --- a/programs/develop/ktcc/trunk/libc/stdio/fflush.c +++ b/programs/develop/ktcc/trunk/libc/stdio/fflush.c @@ -1,7 +1,9 @@ #include int fflush(FILE* file) +// file can be zero, as flush all { - if ((file->mode & 3)==FILE_OPEN_READ) + if (file && (file->mode & 3)==FILE_OPEN_READ) return 0; - return(EOF); -} \ No newline at end of file + + return(0); // always good, as no write buffering +} diff --git a/programs/develop/ktcc/trunk/libc/stdio/fgetc.c b/programs/develop/ktcc/trunk/libc/stdio/fgetc.c index 11a031d84a..e69d94d0f2 100644 --- a/programs/develop/ktcc/trunk/libc/stdio/fgetc.c +++ b/programs/develop/ktcc/trunk/libc/stdio/fgetc.c @@ -2,6 +2,11 @@ int fgetc(FILE* file) { dword res; + if(!file) + { + errno = E_INVALIDPTR; + return EOF; + } if ((file->mode & 3!=FILE_OPEN_READ) && (file->mode & FILE_OPEN_PLUS==0)) return EOF; @@ -17,6 +22,10 @@ int fgetc(FILE* file) file->filepos++; return (int)file->buffer[0]; } - else return(res); + else + { + errno = -res; + return EOF; // errors are < 0 + } } -} \ No newline at end of file +} diff --git a/programs/develop/ktcc/trunk/libc/stdio/fgetpos.c b/programs/develop/ktcc/trunk/libc/stdio/fgetpos.c index c04df6bfb9..469fee688d 100644 --- a/programs/develop/ktcc/trunk/libc/stdio/fgetpos.c +++ b/programs/develop/ktcc/trunk/libc/stdio/fgetpos.c @@ -1,6 +1,12 @@ #include int fgetpos(FILE* file,fpos_t* pos) { + if(!file || !pos) + { + errno = E_INVALIDPTR; + return EOF; + } + *pos=file->filepos; return 0; -} \ No newline at end of file +} diff --git a/programs/develop/ktcc/trunk/libc/stdio/fgets.c b/programs/develop/ktcc/trunk/libc/stdio/fgets.c index 574ec73b0e..1fca699929 100644 --- a/programs/develop/ktcc/trunk/libc/stdio/fgets.c +++ b/programs/develop/ktcc/trunk/libc/stdio/fgets.c @@ -1,12 +1,21 @@ #include -char * fgets ( char * str, int num, FILE * stream ) +char * fgets ( char * str, int num, FILE * file ) +// need to ignore \r\n in text mode { int rd = 0; char c; - while (rd < num - 1) + + if(!file || !str) + { + errno = E_INVALIDPTR; + return NULL; + } + + + while (rd < num - 1) { - c = fgetc(stream); + c = fgetc(file); if (EOF == c) break; if ('\n' == c) { @@ -17,8 +26,8 @@ char * fgets ( char * str, int num, FILE * stream ) str[rd++] = c; } if (0 == rd) return NULL; - else - { + else + { str[rd] = '\0'; return str; } diff --git a/programs/develop/ktcc/trunk/libc/stdio/fopen.c b/programs/develop/ktcc/trunk/libc/stdio/fopen.c index 2b63bfea00..b3b7bd0470 100644 --- a/programs/develop/ktcc/trunk/libc/stdio/fopen.c +++ b/programs/develop/ktcc/trunk/libc/stdio/fopen.c @@ -5,6 +5,9 @@ extern char __argv; extern char __path; +int errno = 0; + + const char* getfullpath(const char *path){ int i,j,relpath_pos,localpath_size; @@ -39,14 +42,20 @@ const char* getfullpath(const char *path){ if (local_path==1) { - i=0x400; + i=FILENAME_MAX; //find local path of program while(*(programpath+i)!='/') { i--; } localpath_size=i; - newpath=malloc(0x400); + newpath=malloc(FILENAME_MAX); + if(!newpath) + { + errno = E_NOMEM; + return NULL; + } + //copy local path to the new path for(i=0;i<=localpath_size;i++) { @@ -61,7 +70,7 @@ const char* getfullpath(const char *path){ } //if we here than path is a relative - i=0x400; + i=FILENAME_MAX; //find local path of program while(*(programpath+i)!='/') { @@ -75,7 +84,12 @@ const char* getfullpath(const char *path){ i++; } filename_size=i; - newpath=malloc(0x400); + newpath=malloc(FILENAME_MAX); + if(!newpath) + { + errno = E_NOMEM; + return NULL; + } //copy local path to the new path for(i=0;i<=localpath_size;i++) { @@ -109,6 +123,11 @@ FILE* fopen(const char* filename, const char *mode) mode++; }else return 0; + if (*mode=='+') + { + imode|=FILE_OPEN_PLUS; + mode++; + } if (*mode=='t') { imode|=FILE_OPEN_TEXT; @@ -121,14 +140,22 @@ FILE* fopen(const char* filename, const char *mode) mode++; } if (*mode!=0) - return 0; + return NULL; res=malloc(sizeof(FILE)); - res->buffer=malloc(256); - res->buffersize=256; - res->filesize=0; - res->filepos=0; - res->mode=imode; - res->filename=(char*)getfullpath(filename); + if (res) + { + res->buffer=malloc(BUFSIZ); + res->buffersize=BUFSIZ; + res->filesize=0; + res->filepos=0; + res->mode=imode; + res->filename=(char*)getfullpath(filename); + } + if(!res || !res->buffer || !res->filename) + { + errno = E_NOMEM; + return NULL; + } if ((imode==FILE_OPEN_READ) || (imode==FILE_OPEN_APPEND)) { diff --git a/programs/develop/ktcc/trunk/libc/stdio/format_print.c b/programs/develop/ktcc/trunk/libc/stdio/format_print.c index 8eed9190d6..5cf6d379c5 100644 --- a/programs/develop/ktcc/trunk/libc/stdio/format_print.c +++ b/programs/develop/ktcc/trunk/libc/stdio/format_print.c @@ -77,7 +77,7 @@ int copy_and_align(char *dest, int width, char *src, int src_len, char sign, int int rc = 0, sign_len; char fill; - fill = (flags & flag_lead_zeros) ? '0' : ' '; + fill = (flags & flag_lead_zeros)&&((flags & flag_left_just)==0) ? '0' : ' '; if(sign == 'x' || sign == 'X') { sign_len = 2; @@ -160,7 +160,7 @@ int formatted_double_to_string_scientific(long double number, int format1, int f if (flags & flag_space_plus) sign = ' '; } // normalize - while (norm_digit < 1.0) { norm_digit *= 10; mul--; } + while (norm_digit < 1.0 && norm_digit > 0) { norm_digit *= 10; mul--; } while (norm_digit >= 10.0) { norm_digit /= 10; mul++; } len = formatted_double_to_string(norm_digit, 0, format2, buf, flags & ~(flag_plus | flag_space_plus)); @@ -612,7 +612,10 @@ int format_print(char *dest, size_t maxlen, const char *fmt0, va_list argp) //prec special case, this is just workaround if (flag_long <= 1) doubledigit = va_arg(argp, double); else if (flag_long == 2) doubledigit = va_arg(argp, long double); - length = formatted_double_to_string(doubledigit, fmt1, fmt2, buf, flags); + if (flags & flag_point) + length = formatted_double_to_string(doubledigit, fmt1, fmt2, buf, flags); + else + length = formatted_double_to_string(doubledigit, fmt1, 1, buf, flags | flag_point); i = formatted_double_to_string_scientific(doubledigit, fmt1, fmt2, buf + sizeof buf / 2, flags); if(length > i) { diff --git a/programs/develop/ktcc/trunk/libc/stdio/format_scan.c b/programs/develop/ktcc/trunk/libc/stdio/format_scan.c index d1abb2d9fd..18de59b0d6 100644 --- a/programs/develop/ktcc/trunk/libc/stdio/format_scan.c +++ b/programs/develop/ktcc/trunk/libc/stdio/format_scan.c @@ -336,11 +336,7 @@ int format_scan(const void *src, const char *fmt, va_list argp, virtual_getc vge else fmt2 = fmt2 * 10 + (*fmt -'0'); break; - case '*': - if (flag_point == 0) - fmt1 = va_arg(argp, int); - else - fmt2 = va_arg(argp, int); + case '*': // ignoring break; case '.': flags |= flag_point; diff --git a/programs/develop/ktcc/trunk/libc/stdio/fprintf.c b/programs/develop/ktcc/trunk/libc/stdio/fprintf.c index 38ca22ec8a..4828555a32 100644 --- a/programs/develop/ktcc/trunk/libc/stdio/fprintf.c +++ b/programs/develop/ktcc/trunk/libc/stdio/fprintf.c @@ -1,23 +1,44 @@ #include #include + + int fprintf(FILE* file, const char* format, ...) { -va_list arg; -char *buf; -int printed; -//int data[4]; - - va_start (arg, format); - buf=malloc(4096*2); //8kb max - //data[0]=(int)&arg-(int)&format; + va_list arg; + va_start (arg, format); + + return vfprintf(file, format, arg); + +} + +int vfprintf ( FILE * file, const char * format, va_list arg ) +{ + char *buf; + int printed, rc = 0; + + if(!file || !format) + { + errno = E_INVALIDPTR; + return errno; + } + + buf=malloc(4096*2); //8kb max + if(!buf) + { + errno = E_NOMEM; + return errno; + } printed=format_print(buf,8191, format,arg); if (file == stderr) debug_out_str(buf); else - fwrite(buf,printed,1,file); + rc = fwrite(buf,printed,1,file); free(buf); - return(printed); + if (rc < 0) + return rc; + else + return(printed); } diff --git a/programs/develop/ktcc/trunk/libc/stdio/fputc.c b/programs/develop/ktcc/trunk/libc/stdio/fputc.c index db8e02cd1f..d416a1734a 100644 --- a/programs/develop/ktcc/trunk/libc/stdio/fputc.c +++ b/programs/develop/ktcc/trunk/libc/stdio/fputc.c @@ -2,8 +2,17 @@ int fputc(int c,FILE* file) { dword res; + if(!file) + { + errno = E_INVALIDPTR; + return EOF; + } - if ((file->mode & 3)==FILE_OPEN_READ) return EOF; + if ((file->mode & 3)==FILE_OPEN_READ) + { + errno = E_ACCESS; + return EOF; + } file->buffer[0]=c; if ((file->mode & 3)==FILE_OPEN_APPEND) @@ -11,25 +20,37 @@ int fputc(int c,FILE* file) file->filepos=file->filesize; file->filesize++; res=_ksys_appendtofile(file->filename,file->filepos,1,file->buffer); - if (res!=0) return(res); + if (res!=0) + { + errno = -res; + return EOF; + } file->filepos++; - return(0); + return c; } if ((file->mode & 3)==FILE_OPEN_WRITE) { if (file->filepos==0) - { //file not craeted + { //file not created res=_ksys_rewritefile(file->filename,1,file->buffer); - if (res!=0) return(res); + if (res!=0) + { + errno = -res; + return EOF; + } file->filepos++; - return 0; + return c; } else - { //file craeted and need append one byte + { //file created and need append one byte res=_ksys_appendtofile(file->filename,file->filepos,1,file->buffer); - if (res!=0) return(res); + if (res!=0) + { + errno = -res; + return EOF; + } file->filepos++; - return 0; + return c; } } } diff --git a/programs/develop/ktcc/trunk/libc/stdio/fputs.c b/programs/develop/ktcc/trunk/libc/stdio/fputs.c new file mode 100644 index 0000000000..b360313a31 --- /dev/null +++ b/programs/develop/ktcc/trunk/libc/stdio/fputs.c @@ -0,0 +1,27 @@ +#include + +int fputs ( const char * str, FILE * file ) +{ + int rc; + + if(!file || !str) + { + errno = E_INVALIDPTR; + return EOF; + } + + if ((file->mode & 3)==FILE_OPEN_READ) + { + errno = E_ACCESS; + return EOF; + } + + while(*str) + { + rc = fputc(*str, file); + if (rc < 0) return rc; + str++; + } + + return 0; +} diff --git a/programs/develop/ktcc/trunk/libc/stdio/fread.c b/programs/develop/ktcc/trunk/libc/stdio/fread.c index 3d2d2bf82c..79a2be53a8 100644 --- a/programs/develop/ktcc/trunk/libc/stdio/fread.c +++ b/programs/develop/ktcc/trunk/libc/stdio/fread.c @@ -6,10 +6,20 @@ int fread(void *buffer,int size,int count,FILE* file) dword res; dword fullsize; - if ((file->mode!=FILE_OPEN_READ) || (file->mode==FILE_OPEN_PLUS)) return 0; + if(!file || !buffer) + { + errno = E_INVALIDPTR; + return 0; + } + + if ((file->mode &3)!=FILE_OPEN_READ && (file->mode & FILE_OPEN_PLUS==0)) + { + errno = E_ACCESS; + return 0; + } fullsize=count*size; - if ((fullsize+file->filepos)>(file->filesize)) + if ((fullsize+file->filepos)>=(file->filesize)) { fullsize=file->filesize-file->filepos; if (fullsize<=0) return(0); @@ -17,10 +27,14 @@ int fread(void *buffer,int size,int count,FILE* file) res=_ksys_readfile(file->filename,file->filepos,fullsize,buffer); if (res==0) - { + { file->filepos=file->filepos+fullsize; fullsize=fullsize/size; return(fullsize); } - else return 0; -} \ No newline at end of file + else + { + errno = -res; + return 0; + } +} diff --git a/programs/develop/ktcc/trunk/libc/stdio/fseek.c b/programs/develop/ktcc/trunk/libc/stdio/fseek.c index 620b043403..813815dfee 100644 --- a/programs/develop/ktcc/trunk/libc/stdio/fseek.c +++ b/programs/develop/ktcc/trunk/libc/stdio/fseek.c @@ -2,6 +2,12 @@ int fseek(FILE* file,long offset,int origin) { fpos_t pos; + if(!file) + { + errno = E_INVALIDPTR; + return errno; + } + if (origin==SEEK_CUR) offset+=file->filepos; else if (origin==SEEK_END) @@ -9,5 +15,5 @@ int fseek(FILE* file,long offset,int origin) else if (origin!=SEEK_SET) return EOF; pos = offset; - return fsetpos(file, &pos); -} \ No newline at end of file + return fsetpos(file, &pos); +} diff --git a/programs/develop/ktcc/trunk/libc/stdio/fsetpos.c b/programs/develop/ktcc/trunk/libc/stdio/fsetpos.c index 0c2d624e83..10f8fe875c 100644 --- a/programs/develop/ktcc/trunk/libc/stdio/fsetpos.c +++ b/programs/develop/ktcc/trunk/libc/stdio/fsetpos.c @@ -1,6 +1,12 @@ #include int fsetpos(FILE* file,const fpos_t * pos) { + if(!file || !pos) + { + errno = E_INVALIDPTR; + return errno; + } + if (*pos>=0) { file->filepos=*pos; @@ -8,4 +14,4 @@ int fsetpos(FILE* file,const fpos_t * pos) } else return EOF; -} \ No newline at end of file +} diff --git a/programs/develop/ktcc/trunk/libc/stdio/ftell.c b/programs/develop/ktcc/trunk/libc/stdio/ftell.c index 20500a9db7..053ce76e2c 100644 --- a/programs/develop/ktcc/trunk/libc/stdio/ftell.c +++ b/programs/develop/ktcc/trunk/libc/stdio/ftell.c @@ -1,5 +1,11 @@ #include long ftell(FILE* file) { + if(!file) + { + errno = E_INVALIDPTR; + return -1L; + } + return file->filepos; -} \ No newline at end of file +} diff --git a/programs/develop/ktcc/trunk/libc/stdio/fwrite.c b/programs/develop/ktcc/trunk/libc/stdio/fwrite.c index 5d498206cd..7c366a8157 100644 --- a/programs/develop/ktcc/trunk/libc/stdio/fwrite.c +++ b/programs/develop/ktcc/trunk/libc/stdio/fwrite.c @@ -6,12 +6,24 @@ int fwrite(void *buffer,int size,int count,FILE* file) dword res; dword fullsize; - if (file->mode==FILE_OPEN_READ) return 0; + if(!file || !buffer) + { + errno = E_INVALIDPTR; + return EOF; + } - if (file->mode==FILE_OPEN_APPEND) + + if ((file->mode & 3)==FILE_OPEN_READ) + { + errno = E_ACCESS; + return 0; + } + + if ((file->mode &3)==FILE_OPEN_APPEND) file->filepos=file->filesize; - fullsize=count*size; - + + fullsize=count*size; + if ((file->filesize)<(file->filepos+fullsize)) file->filesize=file->filepos+fullsize; /* @@ -26,33 +38,39 @@ int fwrite(void *buffer,int size,int count,FILE* file) return(fullsize); } else return(0); - + } */ - if ((file->mode==FILE_OPEN_WRITE) || (file->mode==FILE_OPEN_APPEND)) + if ((file->mode &3)==FILE_OPEN_WRITE || (file->mode&3)==FILE_OPEN_APPEND) // always true, as read checked previous { if (file->filepos==0) - { //file mot craeted yet + { //file mot created yet res=_ksys_rewritefile(file->filename,fullsize,buffer); if (res==0) { file->filepos+=fullsize; fullsize=fullsize/count; return(fullsize); - } - else return(0); + } else + { + errno = -res; + return(0); + } } else - { - res=_ksys_appendtofile(file->filename,file->filepos,fullsize,buffer); + { + res=_ksys_appendtofile(file->filename,file->filepos,fullsize,buffer); if (res==0) { file->filepos+=fullsize; fullsize=fullsize/count; return(fullsize); - } - else return(0); + } else + { + errno = -res; + return(0); + } } } else return(0); -} \ No newline at end of file +} diff --git a/programs/develop/ktcc/trunk/libc/stdio/printf.c b/programs/develop/ktcc/trunk/libc/stdio/printf.c index c318f69066..e9b9851707 100644 --- a/programs/develop/ktcc/trunk/libc/stdio/printf.c +++ b/programs/develop/ktcc/trunk/libc/stdio/printf.c @@ -1,25 +1,32 @@ #include #include #include +#include int printf(const char *format, ...) +{ + va_list arg; + va_start(arg, format); + + return vprintf(format, arg); +} + + +int vprintf ( const char * format, va_list arg ) { int i = 0; int printed_simbols = 0; - va_list arg; char *s; - va_start(arg,format); - i=con_init_console_dll(); - if (i==0) + if (i == 0) { - s=malloc(4096); - printed_simbols=format_print(s,4096,format,arg); + s = malloc(4096); + printed_simbols = format_print(s, 4096, format, arg); con_write_string(s, printed_simbols); free(s); } + return(printed_simbols); } - diff --git a/programs/develop/ktcc/trunk/libc/stdio/rewind.c b/programs/develop/ktcc/trunk/libc/stdio/rewind.c index 4b2f4a1eb3..e35e8d6d6c 100644 --- a/programs/develop/ktcc/trunk/libc/stdio/rewind.c +++ b/programs/develop/ktcc/trunk/libc/stdio/rewind.c @@ -1,5 +1,11 @@ #include void rewind(FILE* file) { + if(!file) + { + errno = E_INVALIDPTR; + return; + } + file->filepos=0; -} \ No newline at end of file +} diff --git a/programs/develop/ktcc/trunk/libc/stdio/snprintf.c b/programs/develop/ktcc/trunk/libc/stdio/snprintf.c index 5e2e6527dd..0db3e146a7 100644 --- a/programs/develop/ktcc/trunk/libc/stdio/snprintf.c +++ b/programs/develop/ktcc/trunk/libc/stdio/snprintf.c @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/programs/develop/ktcc/trunk/libc/stdio/ungetc.c b/programs/develop/ktcc/trunk/libc/stdio/ungetc.c index 5bfe0ea7be..4a91d17e9c 100644 --- a/programs/develop/ktcc/trunk/libc/stdio/ungetc.c +++ b/programs/develop/ktcc/trunk/libc/stdio/ungetc.c @@ -4,13 +4,24 @@ int ungetc(int c,FILE* file) { dword res; - if ((file->mode & 3!=FILE_OPEN_READ) && (file->mode & FILE_OPEN_PLUS==0)) return EOF; + if(!file) + { + errno = E_INVALIDPTR; + return EOF; + } + + if ((file->mode & 3!=FILE_OPEN_READ) && (file->mode & FILE_OPEN_PLUS==0)) + { + errno = E_ACCESS; + return EOF; + } if (file->filepos>file->filesize || file->filepos==0) { + errno = E_EOF; return EOF; } file->filepos--; return c; -} \ No newline at end of file +} diff --git a/programs/develop/ktcc/trunk/libc/stdio/vsnprintf.c b/programs/develop/ktcc/trunk/libc/stdio/vsnprintf.c index 59515649cd..82941198ca 100644 --- a/programs/develop/ktcc/trunk/libc/stdio/vsnprintf.c +++ b/programs/develop/ktcc/trunk/libc/stdio/vsnprintf.c @@ -2,14 +2,13 @@ #include #include -int format_print(char *dest, size_t maxlen, const char *fmt, - va_list argp); - - -int vsnprintf(char *dest, size_t size,const char *format,va_list ap) +int vsnprintf(char *dest, size_t size, const char *format, va_list ap) { - return format_print(dest,size, format, ap); } +int vsprintf (char * dest, const char * format, va_list ap ) +{ + return format_print(dest, 4096, format, ap); +} diff --git a/programs/develop/ktcc/trunk/libc/stdlib/assert.c b/programs/develop/ktcc/trunk/libc/stdlib/assert.c new file mode 100644 index 0000000000..cd13544f7e --- /dev/null +++ b/programs/develop/ktcc/trunk/libc/stdlib/assert.c @@ -0,0 +1,21 @@ +#include +#include +#include +#include + + +void __assert_func (char *file, int line, char *ass) +{ + char buf[100]; + + snprintf(buf,100,"Assertion failed: %s, file %s, line %d\n", ass, file, line); + debug_out_str(buf); + exit(-1); +} + +void __trace_func (char *file, int line, char *msg) +{ + char buf[100]; + snprintf(buf,100,"Trace: %s, file %s, line %d\n", msg, file, line); + debug_out_str(buf); +} diff --git a/programs/develop/ktcc/trunk/libc/stdlib/div.c b/programs/develop/ktcc/trunk/libc/stdlib/div.c new file mode 100644 index 0000000000..159e77e16f --- /dev/null +++ b/programs/develop/ktcc/trunk/libc/stdlib/div.c @@ -0,0 +1,10 @@ +#include + +div_t div (int numer, int denom) +{ + div_t res; + res.quot = numer / denom; + res.rem = numer % denom; + + return res; +} diff --git a/programs/develop/ktcc/trunk/libc/stdlib/tolower.c b/programs/develop/ktcc/trunk/libc/stdlib/tolower.c index 824cd9e06d..75ad383f6e 100644 --- a/programs/develop/ktcc/trunk/libc/stdlib/tolower.c +++ b/programs/develop/ktcc/trunk/libc/stdlib/tolower.c @@ -1,3 +1,4 @@ +#include /* ** return lower-case of c if upper-case, else c */ diff --git a/programs/develop/ktcc/trunk/libc/stdlib/toupper.c b/programs/develop/ktcc/trunk/libc/stdlib/toupper.c index 4139326256..44f6c9afd7 100644 --- a/programs/develop/ktcc/trunk/libc/stdlib/toupper.c +++ b/programs/develop/ktcc/trunk/libc/stdlib/toupper.c @@ -1,3 +1,4 @@ +#include /* ** return upper-case of c if it is lower-case, else c */ diff --git a/programs/develop/ktcc/trunk/libc/string/calloc.c b/programs/develop/ktcc/trunk/libc/string/calloc.c new file mode 100644 index 0000000000..6f2ae76605 --- /dev/null +++ b/programs/develop/ktcc/trunk/libc/string/calloc.c @@ -0,0 +1,13 @@ +#include +#include + +void* calloc (size_t num, size_t size) +{ + size_t bytes = num * size; + void *p = malloc(bytes); + + if(p) + memset(p, 0, bytes); + + return p; +} diff --git a/programs/develop/ktcc/trunk/libc/string/memchr.c b/programs/develop/ktcc/trunk/libc/string/memchr.c index a719079105..f143e0e54a 100644 --- a/programs/develop/ktcc/trunk/libc/string/memchr.c +++ b/programs/develop/ktcc/trunk/libc/string/memchr.c @@ -1,8 +1,10 @@ -void* memchr(const void* buf,int c,int count) +#include + +void* memchr(const void* buf,int c,size_t count) { int i; for (i=0;i + typedef unsigned char uc; -int memcmp(const void* buf1,const void* buf2,int count) +int memcmp(const void* buf1,const void* buf2,size_t count) { int i; for (i=0;i*(uc*)buf2) + if (*(uc*)buf1>*(uc*)buf2) return 1; } return 0; diff --git a/programs/develop/ktcc/trunk/libc/string/memmove.asm b/programs/develop/ktcc/trunk/libc/string/memmove.asm index d8b59ac669..a654d869f5 100644 --- a/programs/develop/ktcc/trunk/libc/string/memmove.asm +++ b/programs/develop/ktcc/trunk/libc/string/memmove.asm @@ -7,29 +7,47 @@ public memcpy public memmove proc memcpy c, to:dword,from:dword,count:dword - - mov ecx,[count] + push esi + push edi + mov ecx,[count] test ecx,ecx jz no_copy_block - - mov esi,[from] + mov esi,[from] mov edi,[to] + cld rep movsb - no_copy_block: +no_copy_block: + pop edi + pop esi + mov eax, [to] ret endp proc memmove c, to:dword,from:dword,count:dword + push esi + push edi mov ecx,[count] test ecx,ecx jz no_copy_block_ - mov esi,[from] mov edi,[to] + cmp esi, edi + je no_copy_block_ + jg copy_ + add esi, ecx + add edi, ecx + dec esi + dec edi + std +copy_: rep movsb - no_copy_block_: + cld +no_copy_block_: + pop edi + pop esi + mov eax,[to] ret -endp \ No newline at end of file +endp diff --git a/programs/develop/ktcc/trunk/libc/string/memset.asm b/programs/develop/ktcc/trunk/libc/string/memset.asm index 17f3dd5a31..3d73257e3b 100644 --- a/programs/develop/ktcc/trunk/libc/string/memset.asm +++ b/programs/develop/ktcc/trunk/libc/string/memset.asm @@ -10,6 +10,6 @@ memset: cld rep stosb .no_set: + mov eax, [esp+8] pop edi ret - \ No newline at end of file diff --git a/programs/develop/ktcc/trunk/libc/string/strcat.c b/programs/develop/ktcc/trunk/libc/string/strcat.c index ba7340a7f0..eb2e181fe2 100644 --- a/programs/develop/ktcc/trunk/libc/string/strcat.c +++ b/programs/develop/ktcc/trunk/libc/string/strcat.c @@ -1,8 +1,10 @@ +#include + char* strcat(char* strDest, const char* strSource) { char* res; res=strDest; while (*strDest) strDest++; - while (*strDest++ = *strSource++) ; + while ((*strDest++ = *strSource++)) ; return res; } diff --git a/programs/develop/ktcc/trunk/libc/string/strchr.c b/programs/develop/ktcc/trunk/libc/string/strchr.c index 1ac97c6de8..6895b62daf 100644 --- a/programs/develop/ktcc/trunk/libc/string/strchr.c +++ b/programs/develop/ktcc/trunk/libc/string/strchr.c @@ -1,10 +1,11 @@ +#include + char* strchr(const char* string, int c) { - while (*string) - { - if (*string==c) + do { + if (*string == (char)c) return (char*)string; - string++; - } - return (char*)0; + } while (*string++); + + return NULL; } diff --git a/programs/develop/ktcc/trunk/libc/string/strcmp.c b/programs/develop/ktcc/trunk/libc/string/strcmp.c index 203c041275..8fc46702de 100644 --- a/programs/develop/ktcc/trunk/libc/string/strcmp.c +++ b/programs/develop/ktcc/trunk/libc/string/strcmp.c @@ -1,3 +1,5 @@ +#include + int strcmp(const char* string1, const char* string2) { while (1) diff --git a/programs/develop/ktcc/trunk/libc/string/strcpy.c b/programs/develop/ktcc/trunk/libc/string/strcpy.c index 850b51909e..61aab01503 100644 --- a/programs/develop/ktcc/trunk/libc/string/strcpy.c +++ b/programs/develop/ktcc/trunk/libc/string/strcpy.c @@ -1,7 +1,9 @@ -char* strcpy(char* strDest,char* strSource) +#include + +char* strcpy(char* strDest,const char* strSource) { char* res; res=strDest; - while(*strDest++ = *strSource++) ; - return res; -} \ No newline at end of file + while((*strDest++ = *strSource++)) ; + return res; +} diff --git a/programs/develop/ktcc/trunk/libc/string/strcspn.c b/programs/develop/ktcc/trunk/libc/string/strcspn.c index 8a4dbc8a3d..31173d698e 100644 --- a/programs/develop/ktcc/trunk/libc/string/strcspn.c +++ b/programs/develop/ktcc/trunk/libc/string/strcspn.c @@ -1,9 +1,11 @@ -int strcspn(const char* string, const char* strCharSet) +#include + +size_t strcspn(const char* string, const char* strCharSet) { const char* temp; int i; i=0; - while(1) + while(*string) { temp=strCharSet; while (*temp!='\0') @@ -14,4 +16,5 @@ int strcspn(const char* string, const char* strCharSet) } i++;string++; } + return i; } diff --git a/programs/develop/ktcc/trunk/libc/string/strdup.c b/programs/develop/ktcc/trunk/libc/string/strdup.c index 6f53813407..8c831d814f 100644 --- a/programs/develop/ktcc/trunk/libc/string/strdup.c +++ b/programs/develop/ktcc/trunk/libc/string/strdup.c @@ -7,6 +7,7 @@ char* strdup(const char* str) int len; len=strlen(str)+1; res=malloc(len); - memcpy(res,str,len); + if(res) + memcpy(res,str,len); return res; } diff --git a/programs/develop/ktcc/trunk/libc/string/strerror.c b/programs/develop/ktcc/trunk/libc/string/strerror.c index 4b38b0d5b1..50e1e829c5 100644 --- a/programs/develop/ktcc/trunk/libc/string/strerror.c +++ b/programs/develop/ktcc/trunk/libc/string/strerror.c @@ -1,4 +1,59 @@ +#include + char* strerror(int err) { - return (char*)0; + char *msg; + switch(err) + { + case 0: + msg = "success"; + break; + case -1: + msg = "end of file"; + break; + case -2: + msg = "function is not supported for the given file system"; + break; + case -3: + msg = "unknown file system"; + break; + case -5: + msg = "file not found"; + break; + case -6: + msg = "end of file, EOF"; + break; + case -7: + msg = "pointer lies outside of application memory"; + break; + case -8: + msg = "disk is full"; + break; + case -9: + msg = "file system error"; + break; + case -10: + msg = "access denied"; + break; + case -11: + msg = "device error"; + break; + case -12: + msg = "file system requires more memory"; + break; + case -30: + msg = "not enough memory"; + break; + case -31: + msg = "file is not executable"; + break; + case -32: + msg = "too many processes"; + break; + default: + msg = "unknown error"; + break; + } + + return msg; } diff --git a/programs/develop/ktcc/trunk/libc/string/strnbrk.c b/programs/develop/ktcc/trunk/libc/string/strnbrk.c index f77d3e8c11..86d1b290b8 100644 --- a/programs/develop/ktcc/trunk/libc/string/strnbrk.c +++ b/programs/develop/ktcc/trunk/libc/string/strnbrk.c @@ -1,3 +1,5 @@ +#include + char* strpbrk(const char* string, const char* strCharSet) { const char* temp; diff --git a/programs/develop/ktcc/trunk/libc/string/strncat.c b/programs/develop/ktcc/trunk/libc/string/strncat.c index 0ddb05db8c..47426c4dcf 100644 --- a/programs/develop/ktcc/trunk/libc/string/strncat.c +++ b/programs/develop/ktcc/trunk/libc/string/strncat.c @@ -1,13 +1,15 @@ -char* strncat(char* strDest,const char* strSource,int count) +#include + +char* strncat(char* strDest,const char* strSource,size_t count) { char* res; res=strDest; - while (*strDest++) ; - while(count-->0) + while (*strDest) strDest++; + while(count-- > 0) { - if(*strDest++ = *strSource++) continue; + if((*strDest++ = *strSource++)) continue; return(res); } *strDest = 0; return res; -} \ No newline at end of file +} diff --git a/programs/develop/ktcc/trunk/libc/string/strncmp.c b/programs/develop/ktcc/trunk/libc/string/strncmp.c index 1eb92f26cf..03a40ffd68 100644 --- a/programs/develop/ktcc/trunk/libc/string/strncmp.c +++ b/programs/develop/ktcc/trunk/libc/string/strncmp.c @@ -1,12 +1,14 @@ -int strncmp(const char* string1, const char* string2, int count) +#include + +int strncmp(const char* string1, const char* string2, size_t count) { - while(count>0 && *string1==*string2) + while(count>0 && (*string1==*string2)) { - if (*string1) return 0; + if ('\0' == *string1) return 0; ++string1; ++string2; --count; } if(count) return (*string1 - *string2); return 0; -} \ No newline at end of file +} diff --git a/programs/develop/ktcc/trunk/libc/string/strncpy.c b/programs/develop/ktcc/trunk/libc/string/strncpy.c index 9c4b9fab2c..b6f658c5f7 100644 --- a/programs/develop/ktcc/trunk/libc/string/strncpy.c +++ b/programs/develop/ktcc/trunk/libc/string/strncpy.c @@ -1,4 +1,6 @@ -char* strncpy(char* strDest,const char* strSource,int count) +#include + +char* strncpy(char* strDest,const char* strSource,size_t count) { char* res; res=strDest; @@ -11,4 +13,4 @@ char* strncpy(char* strDest,const char* strSource,int count) count--; } return res; -} \ No newline at end of file +} diff --git a/programs/develop/ktcc/trunk/libc/string/strrchr.c b/programs/develop/ktcc/trunk/libc/string/strrchr.c index 4eb7166ab0..9594db9fa4 100644 --- a/programs/develop/ktcc/trunk/libc/string/strrchr.c +++ b/programs/develop/ktcc/trunk/libc/string/strrchr.c @@ -1,3 +1,5 @@ +#include + char* strrchr(const char* s,int c) { char* res; diff --git a/programs/develop/ktcc/trunk/libc/string/strrev.c b/programs/develop/ktcc/trunk/libc/string/strrev.c index 8b9cdc86b8..015ad0700c 100644 --- a/programs/develop/ktcc/trunk/libc/string/strrev.c +++ b/programs/develop/ktcc/trunk/libc/string/strrev.c @@ -1,12 +1,14 @@ +#include + char* strrev(char *p) { char *q = p, *res = p, z; while(q && *q) ++q; /* find eos */ - for(--q; p < q; ++p, --q) - { + for(--q; p < q; ++p, --q) + { z = *p; *p = *q; *q = z; } return res; -} \ No newline at end of file +} diff --git a/programs/develop/ktcc/trunk/libc/string/strspn.c b/programs/develop/ktcc/trunk/libc/string/strspn.c index 4224ed810d..22a7fce6a1 100644 --- a/programs/develop/ktcc/trunk/libc/string/strspn.c +++ b/programs/develop/ktcc/trunk/libc/string/strspn.c @@ -1,4 +1,6 @@ -int strspn(const char* string,const char* strCharSet) +#include + +size_t strspn(const char* string,const char* strCharSet) { int i; const char* temp; @@ -6,14 +8,15 @@ int strspn(const char* string,const char* strCharSet) while (*string!='\0') { temp=strCharSet; - while (temp!='\0') + while (*temp!='\0') { if (*temp==*string) break; - } - if (temp=='\0') + temp++; + } + if (*temp=='\0') break; - *string++; + string++; i++; } return i; diff --git a/programs/develop/ktcc/trunk/libc/string/strstr.c b/programs/develop/ktcc/trunk/libc/string/strstr.c index 45a8da2001..72fc2bde51 100644 --- a/programs/develop/ktcc/trunk/libc/string/strstr.c +++ b/programs/develop/ktcc/trunk/libc/string/strstr.c @@ -1,4 +1,4 @@ -#include +#include char* strstr(const char* s, const char* find) { diff --git a/programs/develop/ktcc/trunk/libc/string/strtok.c b/programs/develop/ktcc/trunk/libc/string/strtok.c index 39711d1840..d9ae819aef 100644 --- a/programs/develop/ktcc/trunk/libc/string/strtok.c +++ b/programs/develop/ktcc/trunk/libc/string/strtok.c @@ -1,14 +1,25 @@ -#include "string.h" +#include + char* strtok(char* s,const char* delim) +// non reentrant { - char* res; - if (*s=='\0') - return (char*)0; - s+=strspn(s,delim); - if (*s=='\0') - return (char*)0; - res=s; - s+=strcspn(s,delim); - *s=='\0'; + static char* savep; + char* res; + + if(s) + savep = NULL; + else + s = savep; + + if (*s == '\0') + return NULL; + s += strspn(s, delim); + if (*s == '\0') + return NULL; + res = s; + s += strcspn(s, delim); + savep = s + 1; + *s = '\0'; return res; } + diff --git a/programs/develop/ktcc/trunk/libctest/build.bat b/programs/develop/ktcc/trunk/libctest/build.bat new file mode 100644 index 0000000000..db078a7773 --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/build.bat @@ -0,0 +1,68 @@ +@echo off +echo #################################################### +echo # test libc builder # +echo # usage: build [clean] # +echo #################################################### +rem #### CONFIG SECTION #### +set LIBNAME=libck.a +set INCLUDE=include +set CC=D:\VSProjects\msys-kos32-4.8.2\ktcc\trunk\libc\kos32-tcc.exe +set CFLAGS=-I"%cd%\%INCLUDE%" -Wall +set AR=kos32-ar +set ASM=fasm +set dirs=. +rem #### END OF CONFIG SECTION #### + +set objs= +set target=%1 +if not "%1"=="clean" set target=all + +set INCLUDE="%cd%" +call :Target_%target% + +if ERRORLEVEL 0 goto Exit_OK + +echo Probably at runing has been created error +echo For help send a report... +pause +goto :eof + +:Compile_C + %CC% %CFLAGS% %1 -o "%~dpn1.kex" -lck + if not %errorlevel%==0 goto Error_Failed + set objs=%objs% "%~dpn1.o" +goto :eof + +:Compile_Asm + %ASM% %1 "%~dpn1.o" + if not %errorlevel%==0 goto Error_Failed + set objs=%objs% "%~dpn1.o" +goto :eof + +:Target_clean + echo cleaning ... + for %%a in (%dirs%) do del /Q "%%a\*.o" + for %%a in (%dirs%) do del /Q "%%a\*.kex" +goto :Exit_OK + +:Target_all + echo building all ... + for %%a in (%dirs%) do ( + for %%f in ("%%a\*.asm") do call :Compile_Asm "%%f" + for %%f in ("%%a\*.c") do call :Compile_C "%%f" + ) +:: %AR% -ru %LIBNAME% %objs% +:: if not %errorlevel%==0 goto Error_Failed +goto Exit_OK + +:Error_Failed +echo error: execution failed +pause +exit 1 + +:Exit_OK +echo #################################################### +echo # All operations has been done... # +echo #################################################### +pause +exit 0 \ No newline at end of file diff --git a/programs/develop/ktcc/trunk/libctest/fscanf.c b/programs/develop/ktcc/trunk/libctest/fscanf.c new file mode 100644 index 0000000000..4646a481a6 --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/fscanf.c @@ -0,0 +1,125 @@ +#include +#include +#include "test.h" + +#define TEST(r, f, x, m) ( \ + errno=0, ((r) = (f)) == (x) || \ + (t_error("%s failed (" m ")\n", #f, r, x, strerror(errno)), 0) ) + +#define TEST_S(s, x, m) ( \ + !strcmp((s),(x)) || \ + (t_error("[%s] != [%s] (%s)\n", s, x, m), 0) ) + +static FILE *writetemp(const char *data) +{ + FILE *f = fopen("_tmpfile.tmp", "w+"); + if (!f) return 0; + if (!fwrite(data, strlen(data), 1, f)) { + fclose(f); + return 0; + } + rewind(f); + return f; +} + +int main(void) +{ + int i, x, y; + double u; + char a[100], b[100]; + FILE *f; + + + TEST(i, !!(f=writetemp("hello, world")), 1, "failed to make temp file"); + if (f) { + TEST(i, fscanf(f, "%s %[own]", a, b), 2, "got %d fields, expected %d"); + TEST_S(a, "hello,", "wrong result for %s"); + TEST_S(b, "wo", "wrong result for %[own]"); + TEST(i, fgetc(f), 'r', "'%c' != '%c') (%s)"); + fclose(f); + } + + TEST(i, !!(f=writetemp("ld 0x12 0x34")), 1, "failed to make temp file"); + if (f) { + TEST(i, fscanf(f, "ld %5i%2i", &x, &y), 1, "got %d fields, expected %d"); + TEST(i, x, 0x12, "%d != %d"); + TEST(i, fgetc(f), '3', "'%c' != '%c'"); + fclose(f); + } + + TEST(i, !!(f=writetemp(" 42")), 1, "failed to make temp file"); + if (f) { + x=y=-1; + TEST(i, fscanf(f, " %n%*d%n", &x, &y), 0, "%d != %d"); + TEST(i, x, 6, "%d != %d"); + TEST(i, y, 8, "%d != %d"); + TEST(i, ftell(f), 8, "%d != %d"); + TEST(i, !!feof(f), 1, "%d != %d"); + fclose(f); + } + + TEST(i, !!(f=writetemp("[abc123]....x")), 1, "failed to make temp file"); + if (f) { + x=y=-1; + TEST(i, fscanf(f, "%10[^]]%n%10[].]%n", a, &x, b, &y), 2, "%d != %d"); + TEST_S(a, "[abc123", "wrong result for %[^]]"); + TEST_S(b, "]....", "wrong result for %[].]"); + TEST(i, x, 7, "%d != %d"); + TEST(i, y, 12, "%d != %d"); + TEST(i, ftell(f), 12, "%d != %d"); + TEST(i, feof(f), 0, "%d != %d"); + TEST(i, fgetc(f), 'x', "%d != %d"); + fclose(f); + } + + TEST(i, !!(f=writetemp("0x1.0p12")), 1, "failed to make temp file"); + if (f) { + x=y=-1; + u=-1; + TEST(i, fscanf(f, "%lf%n %d", &u, &x, &y), 1, "%d != %d"); + TEST(u, u, 0.0, "%g != %g"); + TEST(i, x, 1, "%d != %d"); + TEST(i, y, -1, "%d != %d"); + TEST(i, ftell(f), 1, "%d != %d"); + TEST(i, feof(f), 0, "%d != %d"); + TEST(i, fgetc(f), 'x', "%d != %d"); + rewind(f); + TEST(i, fgetc(f), '0', "%d != %d"); + TEST(i, fgetc(f), 'x', "%d != %d"); + TEST(i, fscanf(f, "%lf%n%c %d", &u, &x, a, &y), 3, "%d != %d"); + TEST(u, u, 1.0, "%g != %g"); + TEST(i, x, 3, "%d != %d"); + TEST(i, a[0], 'p', "%d != %d"); + TEST(i, y, 12, "%d != %d"); + TEST(i, ftell(f), 8, "%d != %d"); + TEST(i, !!feof(f), 1, "%d != %d"); + fclose(f); + } + + TEST(i, !!(f=writetemp("1.0 012")), 1, "failed to make temp file"); + if (f) { + x=y=-1; + u=-1; + TEST(i, fscanf(f, "%lf%n %i", &u, &x, &y), 2, "%d != %d"); + TEST(u, u, 1.0, "%g != %g"); + TEST(i, x, 3, "%d != %d"); + TEST(i, y, 10, "%d != %d"); + TEST(i, ftell(f), 13, "%d != %d"); + TEST(i, !!feof(f), 1, "%d != %d"); + fclose(f); + } + + TEST(i, !!(f=writetemp("0xx")), 1, "failed to make temp file"); + if (f) { + x=y=-1; + TEST(i, fscanf(f, "%x%n", &x, &y), 0, "%d != %d"); + TEST(i, x, -1, "%d != %d"); + TEST(i, y, -1, "%d != %d"); + TEST(i, ftell(f), 2, "%d != %d"); + TEST(i, feof(f), 0, "%d != %d"); + fclose(f); + } + + printf("%s finished\n", __FILE__); + return t_status; +} diff --git a/programs/develop/ktcc/trunk/libctest/memmove.c b/programs/develop/ktcc/trunk/libctest/memmove.c new file mode 100644 index 0000000000..789332d395 --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/memmove.c @@ -0,0 +1,186 @@ +/* A minor test-program for memmove. + Copyright (C) 2005 Axis Communications. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Neither the name of Axis Communications nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AXIS COMMUNICATIONS AND ITS CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AXIS + COMMUNICATIONS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. */ + +/* Test moves of 0..MAX bytes; overlapping-src-higher, + overlapping-src-lower and non-overlapping. The overlap varies with + 1..N where N is the size moved. This means an order of MAX**2 + iterations. The size of an octet may seem appropriate for MAX and + makes an upper limit for simple testing. For the CRIS simulator, + making this 256 added 90s to the test-run (2GHz P4) while 64 (4s) was + enough to spot the bugs that had crept in, hence the number chosen. */ +#define MAX 64 + +#include +#include +#include + +#define TOO_MANY_ERRORS 11 +int errors = 0; + +#define DEBUGP \ + if (errors == TOO_MANY_ERRORS) \ + printf ("Further errors omitted\n"); \ + else if (errors < TOO_MANY_ERRORS) \ + printf + +/* A safe target-independent memmove. */ + +void +mymemmove (unsigned char *dest, unsigned char *src, size_t n) +{ + size_t i; + + if ((src <= dest && src + n <= dest) + || src >= dest) + while (n-- > 0) + *dest++ = *src++; + else + { + dest += n; + src += n; + while (n-- > 0) + *--dest = *--src; + } +} + +/* It's either the noinline attribute or forcing the test framework to + pass -fno-builtin-memmove. */ +void +xmemmove (unsigned char *dest, unsigned char *src, size_t n) + __attribute__ ((__noinline__)); + +void +xmemmove (unsigned char *dest, unsigned char *src, size_t n) +{ + void *retp; + retp = memmove (dest, src, n); + + if (retp != dest) + { + errors++; + DEBUGP ("memmove of n bytes returned %p instead of dest=%p\n", + retp, dest); + } +} + + +/* Fill the array with something we can associate with a position, but + not exactly the same as the position index. */ + +void +fill (unsigned char dest[MAX*3]) +{ + size_t i; + for (i = 0; i < MAX*3; i++) + dest[i] = (10 + i) % MAX; +} + +int +main (void) +{ + size_t i; + int errors = 0; + + /* Leave some room before and after the area tested, so we can detect + overwrites of up to N bytes, N being the amount tested. If you + want to test using valgrind, make these malloced instead. */ + unsigned char from_test[MAX*3]; + unsigned char to_test[MAX*3]; + unsigned char from_known[MAX*3]; + unsigned char to_known[MAX*3]; + + /* Non-overlap. */ + for (i = 0; i < MAX; i++) + { + /* Do the memmove first before setting the known array, so we know + it didn't change any of the known array. */ + fill (from_test); + fill (to_test); + xmemmove (to_test + MAX, 1 + from_test + MAX, i); + + fill (from_known); + fill (to_known); + mymemmove (to_known + MAX, 1 + from_known + MAX, i); + + if (memcmp (to_known, to_test, sizeof (to_known)) != 0) + { + errors++; + DEBUGP ("memmove failed non-overlap test for %d bytes\n", i); + } + } + + /* Overlap-from-before. */ + for (i = 0; i < MAX; i++) + { + size_t j; + for (j = 0; j < i; j++) + { + fill (to_test); + xmemmove (to_test + MAX * 2 - i, to_test + MAX * 2 - i - j, i); + + fill (to_known); + mymemmove (to_known + MAX * 2 - i, to_known + MAX * 2 - i - j, i); + + if (memcmp (to_known, to_test, sizeof (to_known)) != 0) + { + errors++; + DEBUGP ("memmove failed for %d bytes," + " with src %d bytes before dest\n", + i, j); + } + } + } + + /* Overlap-from-after. */ + for (i = 0; i < MAX; i++) + { + size_t j; + for (j = 0; j < i; j++) + { + fill (to_test); + xmemmove (to_test + MAX, to_test + MAX + j, i); + + fill (to_known); + mymemmove (to_known + MAX, to_known + MAX + j, i); + + if (memcmp (to_known, to_test, sizeof (to_known)) != 0) + { + errors++; + DEBUGP ("memmove failed when moving %d bytes," + " with src %d bytes after dest\n", + i, j); + } + } + } + +printf("%s finished\n", __FILE__); + + if (errors != 0) + abort (); + exit (0); +} \ No newline at end of file diff --git a/programs/develop/ktcc/trunk/libctest/nulprintf.c b/programs/develop/ktcc/trunk/libctest/nulprintf.c new file mode 100644 index 0000000000..d2ba76e507 --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/nulprintf.c @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2014 by ARM Ltd. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software + * is freely granted, provided that this notice is preserved. + */ + +#include +#include + +const char m[8] = {'M','M','M','M','M','M','M','M'}; + +int main() +{ + printf ("%.*s\n", 8, m); // must print MMMMMMMM + +printf("%s finished\n", __FILE__); + + exit (0); +} \ No newline at end of file diff --git a/programs/develop/ktcc/trunk/libctest/print.inc b/programs/develop/ktcc/trunk/libctest/print.inc new file mode 100644 index 0000000000..f07a6ed1ff --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/print.inc @@ -0,0 +1,28 @@ +#include +#include +//#include +//#include "test.h" + +volatile int t_status = 0; + +int t_printf(const char *s, ...) +{ + va_list ap; + char buf[512]; + int n; + + t_status = 1; + va_start(ap, s); + n = vsnprintf(buf, sizeof buf, s, ap); + va_end(ap); + if (n < 0) + n = 0; + else if (n >= sizeof buf) { + n = sizeof buf; + buf[n - 1] = '0'; + buf[n - 2] = '.'; + buf[n - 3] = '.'; + buf[n - 4] = '.'; + } + return printf("%s\n", buf); +} diff --git a/programs/develop/ktcc/trunk/libctest/qsort.c b/programs/develop/ktcc/trunk/libctest/qsort.c new file mode 100644 index 0000000000..c150c36a9a --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/qsort.c @@ -0,0 +1,173 @@ +//#include +#include +#include +#include +#include "test.h" + +static int scmp(const void *a, const void *b) +{ + return strcmp(*(char **)a, *(char **)b); +} + +static int icmp(const void *a, const void *b) +{ + return *(int*)a - *(int*)b; +} + +static int ccmp(const void *a, const void *b) +{ + return *(char*)a - *(char*)b; +} + +static int cmp64(const void *a, const void *b) +{ + const uint64_t *ua = a, *ub = b; + return *ua < *ub ? -1 : *ua != *ub; +} + +/* 26 items -- even */ +static const char *s[] = { + "Bob", "Alice", "John", "Ceres", + "Helga", "Drepper", "Emeralda", "Zoran", + "Momo", "Frank", "Pema", "Xavier", + "Yeva", "Gedun", "Irina", "Nono", + "Wiener", "Vincent", "Tsering", "Karnica", + "Lulu", "Quincy", "Osama", "Riley", + "Ursula", "Sam" +}; +static const char *s_sorted[] = { + "Alice", "Bob", "Ceres", "Drepper", + "Emeralda", "Frank", "Gedun", "Helga", + "Irina", "John", "Karnica", "Lulu", + "Momo", "Nono", "Osama", "Pema", + "Quincy", "Riley", "Sam", "Tsering", + "Ursula", "Vincent", "Wiener", "Xavier", + "Yeva", "Zoran" +}; + +/* 23 items -- odd, prime */ +static int n[] = { + 879045, 394, 99405644, 33434, 232323, 4334, 5454, + 343, 45545, 454, 324, 22, 34344, 233, 45345, 343, + 848405, 3434, 3434344, 3535, 93994, 2230404, 4334 +}; +static int n_sorted[] = { + 22, 233, 324, 343, 343, 394, 454, 3434, + 3535, 4334, 4334, 5454, 33434, 34344, 45345, 45545, + 93994, 232323, 848405, 879045, 2230404, 3434344, 99405644 +}; + +static void str_test(const char **a, const char **a_sorted, int len) +{ + int i; + qsort(a, len, sizeof *a, scmp); + for (i=0; i + +// TODO: use large period prng +static uint64_t seed = -1; +static uint32_t rand32(void) +{ + seed = 6364136223846793005ULL*seed + 1; + return seed >> 32; +} +static uint64_t rand64(void) +{ + uint64_t u = rand32(); + return u<<32 | rand32(); +} +static double frand() +{ + return rand64() * 0x1p-64; +} +static float frandf() +{ + return rand32() * 0x1p-32f; +} +static long double frandl() +{ + return rand64() * 0x1p-64L +#if LDBL_MANT_DIG > 64 ++ rand64() * 0x1p-128L +#endif +; +} + +void t_randseed(uint64_t s) +{ + seed = s; +} + +/* uniform random in [0,n), n > 0 must hold */ +uint64_t t_randn(uint64_t n) +{ + uint64_t r, m; + + /* m is the largest multiple of n */ + m = -1; + m -= m%n; + while ((r = rand64()) >= m); + return r%n; +} + +/* uniform on [a,b], a <= b must hold */ +uint64_t t_randint(uint64_t a, uint64_t b) +{ + uint64_t n = b - a + 1; + if (n) + return a + t_randn(n); + return rand64(); +} + +/* shuffle the elements of p and q until the elements in p are well shuffled */ +static void shuffle2(uint64_t *p, uint64_t *q, size_t np, size_t nq) +{ + size_t r; + uint64_t t; + + while (np) { + r = t_randn(nq+np--); + t = p[np]; + if (r < nq) { + p[np] = q[r]; + q[r] = t; + } else { + p[np] = p[r-nq]; + p[r-nq] = t; + } + } +} + +/* shuffle the elements of p */ +void t_shuffle(uint64_t *p, size_t n) +{ + shuffle2(p,0,n,0); +} + +void t_randrange(uint64_t *p, size_t n) +{ + size_t i; + for (i = 0; i < n; i++) + p[i] = i; + t_shuffle(p, n); +} + +/* hash table insert, 0 means empty, v > 0 must hold, len is power-of-2 */ +static int insert(uint64_t *tab, size_t len, uint64_t v) +{ + size_t i = v & (len-1); + size_t j = 1; + + while (tab[i]) { + if (tab[i] == v) + return -1; + i += j++; + i &= len-1; + } + tab[i] = v; + return 0; +} + +/* choose k unique numbers from [0,n), k <= n */ +int t_choose(uint64_t n, size_t k, uint64_t *p) +{ + uint64_t *tab; + size_t i, j, len; + + if (n < k) + return -1; + + if (n < 16) { + /* no alloc */ + while (k) + if (t_randn(n--) < k) + p[--k] = n; + return 0; + } + + if (k < 8) { + /* no alloc, n > 15 > 2*k */ + for (i = 0; i < k;) { + p[i] = t_randn(n); + for (j = 0; p[j] != p[i]; j++); + if (j == i) + i++; + } + return 0; + } + + // TODO: if k < n/k use k*log(k) solution without alloc + + if (n < 5*k && (n-k)*sizeof *tab < (size_t)-1) { + /* allocation is n-k < 4*k */ + tab = malloc((n-k) * sizeof *tab); + if (!tab) + return -1; + for (i = 0; i < k; i++) + p[i] = i; + for (; i < n; i++) + tab[i-k] = i; + if (k < n-k) + shuffle2(p, tab, k, n-k); + else + shuffle2(tab, p, n-k, k); + free(tab); + return 0; + } + + /* allocation is 2*k <= len < 4*k */ + for (len = 16; len < 2*k; len *= 2); + tab = calloc(len, sizeof *tab); + if (!tab) + return -1; + for (i = 0; i < k; i++) + while (insert(tab, len, t_randn(n)+1)); + for (i = 0; i < len; i++) + if (tab[i]) + *p++ = tab[i]-1; + free(tab); + return 0; +} + diff --git a/programs/develop/ktcc/trunk/libctest/readme.txt b/programs/develop/ktcc/trunk/libctest/readme.txt new file mode 100644 index 0000000000..3905ab969b --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/readme.txt @@ -0,0 +1,34 @@ +most test adapted from "musl-libctest-master" project +some taken from newlib + +Status or tests + +---NOT TESTED--- +no library fns realized +qsort +strtol +time + +---HANG--- +sscanf +>TEST_F(0x1234p56) + + +---STACK IS SMALL--- +strtod_long +tstring + + +--other-- +fscanf +-?scanf ignores width specs, '*' and [chars], cant read %a float +-%n counts as parameter + +snprintf +-some format misturbances + +ungetc +-ungetc fails if filepos == 0 - no tricks + +all file ops limited to 2Gb + diff --git a/programs/develop/ktcc/trunk/libctest/snprintf.c b/programs/develop/ktcc/trunk/libctest/snprintf.c new file mode 100644 index 0000000000..49ec73d38f --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/snprintf.c @@ -0,0 +1,188 @@ +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 700 +#endif +#include +#include +//#include +//#include +#include +#include "test.h" + +#define DISABLE_SLOW_TESTS + +#define TEST(r, f, x, m) ( \ + ((r) = (f)) == (x) || \ + (t_error("%s failed (" m ")\n", #f, r, x), 0) ) + +#define TEST_S(s, x, m) ( \ + !strcmp((s),(x)) || \ + (t_error("[%s] != [%s] (%s)\n", s, x, m), 0) ) + +static const struct { + const char *fmt; + int i; + const char *expect; +} int_tests[] = { + /* width, precision, alignment */ + { "%04d", 12, "0012" }, + { "%.3d", 12, "012" }, + { "%3d", 12, " 12" }, + { "%-3d", 12, "12 " }, + { "%+3d", 12, "+12" }, + { "%+-5d", 12, "+12 " }, + { "%+- 5d", 12, "+12 " }, + { "%- 5d", 12, " 12 " }, + { "% d", 12, " 12" }, + { "%0-5d", 12, "12 " }, + { "%-05d", 12, "12 " }, + + /* ...explicit precision of 0 shall be no characters. */ + { "%.0d", 0, "" }, + { "%.0o", 0, "" }, + { "%#.0d", 0, "" }, + { "%#.0o", 0, "" }, + { "%#.0x", 0, "" }, + + /* ...but it still has to honor width and flags. */ + { "%2.0u", 0, " " }, + { "%02.0u", 0, " " }, + { "%2.0d", 0, " " }, + { "%02.0d", 0, " " }, + { "% .0d", 0, " " }, + { "%+.0d", 0, "+" }, + + /* hex: test alt form and case */ + { "%x", 63, "3f" }, + { "%#x", 63, "0x3f" }, + { "%X", 63, "3F" }, + + /* octal: test alt form */ + { "%o", 15, "17" }, + { "%#o", 15, "017" }, + + { NULL, 0.0, NULL } +}; + +static const struct { + const char *fmt; + double f; + const char *expect; +} fp_tests[] = { + /* basic form, handling of exponent/precision for 0 */ + { "%a", 0.0, "0x0p+0" }, + { "%e", 0.0, "0.000000e+00" }, + { "%f", 0.0, "0.000000" }, + { "%g", 0.0, "0" }, + { "%#g", 0.0, "0.00000" }, + { "%la", 0.0, "0x0p+0" }, + { "%le", 0.0, "0.000000e+00" }, + { "%lf", 0.0, "0.000000" }, + { "%lg", 0.0, "0" }, + { "%#lg", 0.0, "0.00000" }, + + /* rounding */ + { "%f", 1.1, "1.100000" }, + { "%f", 1.2, "1.200000" }, + { "%f", 1.3, "1.300000" }, + { "%f", 1.4, "1.400000" }, + { "%f", 1.5, "1.500000" }, + { "%.4f", 1.06125, "1.0613" }, /* input is not representible exactly as double */ + { "%.4f", 1.03125, "1.0312" }, /* 0x1.08p0 */ + { "%.2f", 1.375, "1.38" }, + { "%.1f", 1.375, "1.4" }, + { "%.1lf", 1.375, "1.4" }, + { "%.15f", 1.1, "1.100000000000000" }, + { "%.16f", 1.1, "1.1000000000000001" }, + { "%.17f", 1.1, "1.10000000000000009" }, + { "%.2e", 1500001.0, "1.50e+06" }, + { "%.2e", 1505000.0, "1.50e+06" }, + { "%.2e", 1505000.00000095367431640625, "1.51e+06" }, + { "%.2e", 1505001.0, "1.51e+06" }, + { "%.2e", 1506000.0, "1.51e+06" }, + + /* correctness in DBL_DIG places */ + { "%.15g", 1.23456789012345, "1.23456789012345" }, + + /* correct choice of notation for %g */ + { "%g", 0.0001, "0.0001" }, + { "%g", 0.00001, "1e-05" }, + { "%g", 123456, "123456" }, + { "%g", 1234567, "1.23457e+06" }, + { "%.7g", 1234567, "1234567" }, + { "%.7g", 12345678, "1.234568e+07" }, + { "%.8g", 0.1, "0.1" }, + { "%.9g", 0.1, "0.1" }, + { "%.10g", 0.1, "0.1" }, + { "%.11g", 0.1, "0.1" }, + + /* pi in double precision, printed to a few extra places */ + { "%.15f", M_PI, "3.141592653589793" }, + { "%.18f", M_PI, "3.141592653589793116" }, + + /* exact conversion of large integers */ + { "%.0f", 340282366920938463463374607431768211456.0, + "340282366920938463463374607431768211456" }, + + { NULL, 0.0, NULL } +}; + +int main(void) +{ + int i, j, k; + char b[2000]; + + TEST(i, snprintf(0, 0, "%d", 123456), 6, "length returned %d != %d"); + TEST(i, snprintf(0, 0, "%.4s", "hello"), 4, "length returned %d != %d"); + TEST(i, snprintf(b, 0, "%.0s", "goodbye"), 0, "length returned %d != %d"); + + strcpy(b, "xxxxxxxx"); + TEST(i, snprintf(b, 4, "%d", 123456), 6, "length returned %d != %d"); + TEST_S(b, "123", "incorrect output"); + TEST(i, b[5], 'x', "buffer overrun"); + + /* Perform ascii arithmetic to test printing tiny doubles */ + TEST(i, snprintf(b, sizeof b, "%.1022f", 0x1p-1021), 1024, "%d != %d"); + b[1] = '0'; + for (i=0; i<1021; i++) { + for (k=0, j=1023; j>0; j--) { + if (b[j]<'5') b[j]+=b[j]-'0'+k, k=0; + else b[j]+=b[j]-'0'-10+k, k=1; + } + } + TEST(i, b[1], '1', "'%c' != '%c'"); + for (j=2; b[j]=='0'; j++); + TEST(i, j, 1024, "%d != %d"); + + +#ifndef DISABLE_SLOW_TESTS + errno = 0; + TEST(i, snprintf(NULL, 0, "%.*u", 2147483647, 0), 2147483647, "cannot print max length %d"); + TEST(i, snprintf(NULL, 0, "%.*u ", 2147483647, 0), -1, "integer overflow %d"); + TEST(i, errno, EOVERFLOW, "after overflow: %d != %d"); +#endif + for (j=0; int_tests[j].fmt; j++) { + i = snprintf(b, sizeof b, int_tests[j].fmt, int_tests[j].i); + if (i != strlen(int_tests[j].expect)) { + t_error("snprintf(b, sizeof b, \"%s\", %d) returned %d wanted %d\n", + int_tests[j].fmt, int_tests[j].i, i, strlen(int_tests[j].expect)); + } + if (strcmp(b, int_tests[j].expect) != 0) + t_error("bad integer conversion fmt[%s]: got \"%s\", want \"%s\"\n", int_tests[j].fmt, b, int_tests[j].expect); + } + + for (j=0; fp_tests[j].fmt; j++) { + i = snprintf(b, sizeof b, fp_tests[j].fmt, fp_tests[j].f); + if (i != strlen(fp_tests[j].expect)) { + t_error("snprintf(b, sizeof b, \"%s\", %f) returned %d wanted %d\n", + fp_tests[j].fmt, fp_tests[j].f, i, strlen(fp_tests[j].expect)); + } + if (strcmp(b, fp_tests[j].expect) != 0) + t_error("bad floating-point conversion: got \"%s\", want \"%s\"\n", b, fp_tests[j].expect); + } + + TEST(i, snprintf(0, 0, "%.4a", 1.0), 11, "%d != %d"); + + printf("%s finished\n", __FILE__); + + return t_status; +} diff --git a/programs/develop/ktcc/trunk/libctest/sscanf.c b/programs/develop/ktcc/trunk/libctest/sscanf.c new file mode 100644 index 0000000000..c748bd753e --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/sscanf.c @@ -0,0 +1,89 @@ +#include +#include +#include +//#include +#include "test.h" + +#define TEST(r, f, x, m) ( \ + ((r) = (f)) == (x) || \ + (t_error("%s failed (" m ")\n", #f, r, x), 0) ) + +#define TEST_S(s, x, m) ( \ + !strcmp((s),(x)) || \ + (t_error("[%s] != [%s] (%s)\n", s, x, m), 0) ) + +#define TEST_F(x) ( \ + TEST(i, sscanf(# x, "%lf", &d), 1, "got %d fields, expected %d"), \ + TEST(t, d, (double)x, "%g != %g") ) + +int main(void) +{ + int i; + char a[100], b[100]; + int x, y, z, u, v; + double d, t; +/* + TEST(i, sscanf("hello, world\n", "%s %s", a, b), 2, "only %d fields, expected %d"); + TEST_S(a, "hello,", ""); + TEST_S(b, "world", ""); + + TEST(i, sscanf("hello, world\n", "%[hel]%s", a, b), 2, "only %d fields, expected %d"); + TEST_S(a, "hell", ""); + TEST_S(b, "o,", ""); + + TEST(i, sscanf("hello, world\n", "%[hel] %s", a, b), 2, "only %d fields, expected %d"); + TEST_S(a, "hell", ""); + TEST_S(b, "o,", ""); + + a[8] = 'X'; + a[9] = 0; + TEST(i, sscanf("hello, world\n", "%8c%8c", a, b), 1, "%d fields, expected %d"); + TEST_S(a, "hello, wX", ""); +*/ + TEST(i, sscanf("56789 0123 56a72", "%2d%d%*d %[0123456789]\n", &x, &y, a), 3, "only %d fields, expected %d"); + TEST(i, x, 56, "%d != %d"); + TEST(i, y, 789, "%d != %d"); + TEST_S(a, "56", ""); + + TEST(i, sscanf("011 0x100 11 0x100 100", "%i %i %o %x %x\n", &x, &y, &z, &u, &v), 5, "only %d fields, expected %d"); + TEST(i, x, 9, "%d != %d"); + TEST(i, y, 256, "%d != %d"); + TEST(i, z, 9, "%d != %d"); + TEST(i, u, 256, "%d != %d"); + TEST(i, v, 256, "%d != %d"); + + TEST(i, sscanf("20 xyz", "%d %d\n", &x, &y), 1, "only %d fields, expected %d"); + TEST(i, x, 20, "%d != %d"); + + TEST(i, sscanf("xyz", "%d %d\n", &x, &y), 0, "got %d fields, expected no match (%d)"); + + TEST(i, sscanf("", "%d %d\n", &x, &y), -1, "got %d fields, expected input failure (%d)"); + + TEST(i, sscanf(" 12345 6", "%2d%d%d", &x, &y, &z), 3, "only %d fields, expected %d"); + TEST(i, x, 12, "%d != %d"); + TEST(i, y, 345, "%d != %d"); + TEST(i, z, 6, "%d != %d"); + + TEST(i, sscanf(" 0x12 0x34", "%5i%2i", &x, &y), 1, "got %d fields, expected %d"); + TEST(i, x, 0x12, "%d != %d"); + + TEST_F(123); + TEST_F(123.0); + TEST_F(123.0e+0); + TEST_F(123.0e+4); + TEST_F(1.234e1234); + TEST_F(1.234e-1234); + TEST_F(1.234e56789); + TEST_F(1.234e-56789); + TEST_F(-0.5); + TEST_F(0.1); + TEST_F(0.2); + TEST_F(0.1e-10); +// TEST_F(0x1234p56); hangs on + + TEST(i, sscanf("10e", "%lf", &d), 0, "got %d fields, expected no match (%d)"); + TEST(i, sscanf("", "%lf\n", &d), -1, "got %d fields, expected input failure (%d)"); + + printf("%s finished\n", __FILE__); + return t_status; +} diff --git a/programs/develop/ktcc/trunk/libctest/string.c b/programs/develop/ktcc/trunk/libctest/string.c new file mode 100644 index 0000000000..22b469a7a2 --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/string.c @@ -0,0 +1,147 @@ +#define _BSD_SOURCE +#include +#include +#include +#include "test.h" + +#ifndef min +#define min(a,b) ((a 0 && nsrc >= size) + dst[size - 1] = '\0'; + + return nsrc; +} + +size_t strlcat(char *dst, const char *src, size_t size) +{ + int ndest = strlen(dst); + int nsrc = strlen(src); + if (size > ndest + 1) + { + strncat(dst, src, size - ndest - 1); + if (size > 0 && nsrc + ndest >= size) + dst[size - 1] = '\0'; + } + + return nsrc + ndest; +} + + + +/* r = place to store result + * f = function call to test (or any expression) + * x = expected result + * m = message to print on failure (with formats for r & x) +**/ + +#define TEST(r, f, x, m) ( \ + ((r) = (f)) == (x) || \ + (t_error("%s failed (" m ")\n", #f, r, x), 0) ) + +#define TEST_S(s, x, m) ( \ + !strcmp((s),(x)) || \ + (t_error("[%s] != [%s] (%s)\n", s, x, m), 0) ) + +int main(void) +{ + char b[32]; + char *s; + int i; + + b[16]='a'; b[17]='b'; b[18]='c'; b[19]=0; + TEST(s, strcpy(b, b+16), b, "wrong return %p != %p"); + TEST_S(s, "abc", "strcpy gave incorrect string"); + TEST(s, strcpy(b+1, b+16), b+1, "wrong return %p != %p"); + TEST_S(s, "abc", "strcpy gave incorrect string"); + TEST(s, strcpy(b+2, b+16), b+2, "wrong return %p != %p"); + TEST_S(s, "abc", "strcpy gave incorrect string"); + TEST(s, strcpy(b+3, b+16), b+3, "wrong return %p != %p"); + TEST_S(s, "abc", "strcpy gave incorrect string"); + + TEST(s, strcpy(b+1, b+17), b+1, "wrong return %p != %p"); + TEST_S(s, "bc", "strcpy gave incorrect string"); + TEST(s, strcpy(b+2, b+18), b+2, "wrong return %p != %p"); + TEST_S(s, "c", "strcpy gave incorrect string"); + TEST(s, strcpy(b+3, b+19), b+3, "wrong return %p != %p"); + TEST_S(s, "", "strcpy gave incorrect string"); + + TEST(s, memset(b, 'x', sizeof b), b, "wrong return %p != %p"); + TEST(s, strncpy(b, "abc", sizeof b - 1), b, "wrong return %p != %p"); + TEST(i, memcmp(b, "abc\0\0\0\0", 8), 0, "strncpy fails to zero-pad dest"); + TEST(i, b[sizeof b - 1], 'x', "strncpy overruns buffer when n > strlen(src)"); + + b[3] = 'x'; b[4] = 0; + strncpy(b, "abc", 3); + TEST(i, b[2], 'c', "strncpy fails to copy last byte: %hhu != %hhu"); + TEST(i, b[3], 'x', "strncpy overruns buffer to null-terminate: %hhu != %hhu"); + + TEST(i, !strncmp("abcd", "abce", 3), 1, "strncmp compares past n"); + TEST(i, !!strncmp("abc", "abd", 3), 1, "strncmp fails to compare n-1st byte"); + + strcpy(b, "abc"); + TEST(s, strncat(b, "123456", 3), b, "%p != %p"); + TEST(i, b[6], 0, "strncat failed to null-terminate (%d)"); + TEST_S(s, "abc123", "strncat gave incorrect string"); + + strcpy(b, "aaababccdd0001122223"); + TEST(s, strchr(b, 'b'), b+3, "%p != %p"); + TEST(s, strrchr(b, 'b'), b+5, "%p != %p"); + TEST(i, strspn(b, "abcd"), 10, "%d != %d"); + TEST(i, strcspn(b, "0123"), 10, "%d != %d"); + TEST(s, strpbrk(b, "0123"), b+10, "%d != %d"); + + strcpy(b, "abc 123; xyz; foo"); + TEST(s, strtok(b, " "), b, "%p != %p"); + TEST_S(s, "abc", "strtok result"); + + TEST(s, strtok(NULL, ";"), b+4, "%p != %p"); + TEST_S(s, " 123", "strtok result"); + + TEST(s, strtok(NULL, " ;"), b+11, "%p != %p"); + TEST_S(s, "xyz", "strtok result"); + + TEST(s, strtok(NULL, " ;"), b+16, "%p != %p"); + TEST_S(s, "foo", "strtok result"); + + memset(b, 'x', sizeof b); + TEST(i, strlcpy(b, "abc", sizeof b - 1), 3, "length %d != %d"); + TEST(i, b[3], 0, "strlcpy did not null-terminate short string (%d)"); + TEST(i, b[4], 'x', "strlcpy wrote extra bytes (%d)"); + + memset(b, 'x', sizeof b); + TEST(i, strlcpy(b, "abc", 2), 3, "length %d != %d"); + TEST(i, b[0], 'a', "strlcpy did not copy character %d"); + TEST(i, b[1], 0, "strlcpy did not null-terminate long string (%d)"); + + memset(b, 'x', sizeof b); + TEST(i, strlcpy(b, "abc", 3), 3, "length %d != %d"); + TEST(i, b[2], 0, "strlcpy did not null-terminate l-length string (%d)"); + + TEST(i, strlcpy(NULL, "abc", 0), 3, "length %d != %d"); + + memcpy(b, "abc\0\0\0x\0", 8); + TEST(i, strlcat(b, "123", sizeof b), 6, "length %d != %d"); + TEST_S(b, "abc123", "strlcat result"); + + memcpy(b, "abc\0\0\0x\0", 8); + TEST(i, strlcat(b, "123", 6), 6, "length %d != %d"); + TEST_S(b, "abc12", "strlcat result"); + TEST(i, b[6], 'x', "strlcat wrote past string %d != %d"); + + memcpy(b, "abc\0\0\0x\0", 8); + TEST(i, strlcat(b, "123", 4), 6, "length %d != %d"); + TEST_S(b, "abc", "strlcat result"); + + memcpy(b, "abc\0\0\0x\0", 8); + TEST(i, strlcat(b, "123", 3), 6, "length %d != %d"); + TEST_S(b, "abc", "strlcat result"); + + printf("%s finished\n", __FILE__); + return t_status; +} diff --git a/programs/develop/ktcc/trunk/libctest/string_memcpy.c b/programs/develop/ktcc/trunk/libctest/string_memcpy.c new file mode 100644 index 0000000000..6500f7a1a7 --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/string_memcpy.c @@ -0,0 +1,56 @@ +#include +#include +//#include +#include "test.h" + +static char buf[512]; + +static void *(*volatile pmemcpy)(void *restrict, const void *restrict2, size_t); + +static void *aligned(void *p) { + return (void*)(((uintptr_t)p + 63) & -64U); +} + +#define N 80 +static void test_align(int dalign, int salign, int len) +{ + char *src = aligned(buf); + char *dst = aligned(buf + 128); + char *want = aligned(buf + 256); + char *p; + int i; + + if (salign + len > N || dalign + len > N) + abort(); + for (i = 0; i < N; i++) { + src[i] = '#'; + dst[i] = want[i] = ' '; + } + for (i = 0; i < len; i++) + src[salign+i] = want[dalign+i] = '0'+i; + p = pmemcpy(dst+dalign, src+salign, len); + if (p != dst+dalign) + t_error("memcpy(%p,...) returned %p\n", dst+dalign, p); + for (i = 0; i < N; i++) + if (dst[i] != want[i]) { + t_error("memcpy(align %d, align %d, %d) failed\n", dalign, salign, len); + t_printf("got : %.*s\n", dalign+len+1, dst); + t_printf("want: %.*s\n", dalign+len+1, want); + break; + } +} + +int main(void) +{ + int i,j,k; + + pmemcpy = memcpy; + + for (i = 0; i < 16; i++) + for (j = 0; j < 16; j++) + for (k = 0; k < 64; k++) + test_align(i,j,k); + + printf("%s finished\n", __FILE__); + return t_status; +} diff --git a/programs/develop/ktcc/trunk/libctest/string_memset.c b/programs/develop/ktcc/trunk/libctest/string_memset.c new file mode 100644 index 0000000000..e2c93f1399 --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/string_memset.c @@ -0,0 +1,71 @@ +#include +#include +//#include +#include "test.h" + +static char buf[512]; + +static void *(*volatile pmemset)(void *, int, size_t); + +static void *aligned(void *p) +{ + return (void*)(((uintptr_t)p + 63) & -64U); +} + +#define N 80 +static void test_align(int align, int len) +{ + char *s = aligned(buf); + char *want = aligned(buf + 256); + char *p; + int i; + + if (align + len > N) + abort(); + for (i = 0; i < N; i++) + s[i] = want[i] = ' '; + for (i = 0; i < len; i++) + want[align+i] = '#'; + p = pmemset(s+align, '#', len); + if (p != s+align) + t_error("memset(%p,...) returned %p\n", s+align, p); + for (i = 0; i < N; i++) + if (s[i] != want[i]) { + t_error("memset(align %d, '#', %d) failed\n", align, len); + t_printf("got : %.*s\n", align+len+1, s); + t_printf("want: %.*s\n", align+len+1, want); + break; + } +} + +static void test_value(int c) +{ + int i; + + pmemset(buf, c, 10); + for (i = 0; i < 10; i++) + if ((unsigned char)buf[i] != (unsigned char)c) { + t_error("memset(%d) failed: got %d\n", c, buf[i]); + break; + } +} + +int main(void) +{ + int i,j,k; + + pmemset = memset; + + for (i = 0; i < 16; i++) + for (j = 0; j < 64; j++) + test_align(i,j); + + test_value('c'); + test_value(0); + test_value(-1); + test_value(-5); + test_value(0xab); + + printf("%s finished\n", __FILE__); + return t_status; +} diff --git a/programs/develop/ktcc/trunk/libctest/string_strchr.c b/programs/develop/ktcc/trunk/libctest/string_strchr.c new file mode 100644 index 0000000000..b687a162fe --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/string_strchr.c @@ -0,0 +1,60 @@ +#include +#include +#include "test.h" + +#define N(s, c) { \ + char *p = s; \ + char *q = strchr(p, c); \ + if (q) \ + t_error("strchr(%s,%s) returned str+%d, wanted 0\n", #s, #c, q-p); \ +} + +#define T(s, c, n) { \ + char *p = s; \ + char *q = strchr(p, c); \ + if (q == 0) \ + t_error("strchr(%s,%s) returned 0, wanted str+%d\n", #s, #c, n); \ + else if (q - p != n) \ + t_error("strchr(%s,%s) returned str+%d, wanted str+%d\n", #s, #c, q-p, n); \ +} + +int main(void) +{ + int i; + char a[128]; + char s[256]; + + for (i = 0; i < 128; i++) + a[i] = (i+1) & 127; + for (i = 0; i < 256; i++) + *((unsigned char*)s+i) = i+1; + + N("", 'a') + N("a", 'b') + N("abc abc", 'x') + N(a, 128) + N(a, 255) + + T("", 0, 0) + T("a", 'a', 0) + T("a", 'a'+256, 0) + T("a", 0, 1) + T("ab", 'b', 1) + T("aab", 'b', 2) + T("aaab", 'b', 3) + T("aaaab", 'b', 4) + T("aaaaab", 'b', 5) + T("aaaaaab", 'b', 6) + T("abc abc", 'c', 2) + T(s, 1, 0) + T(s, 2, 1) + T(s, 10, 9) + T(s, 11, 10) + T(s, 127, 126) + T(s, 128, 127) + T(s, 255, 254) + T(s, 0, 255) + + printf("%s finished\n", __FILE__); + return t_status; +} diff --git a/programs/develop/ktcc/trunk/libctest/string_strcspn.c b/programs/develop/ktcc/trunk/libctest/string_strcspn.c new file mode 100644 index 0000000000..ea207a4962 --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/string_strcspn.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include "test.h" + +#define T(s, c, n) { \ + char *p = s; \ + char *q = c; \ + size_t r = strcspn(p, q); \ + if (r != n) \ + t_error("strcspn(%s,%s) returned %lu, wanted %lu\n", #s, #c, (unsigned long)r, (unsigned long)(n)); \ +} + +int main(void) +{ + int i; + char a[128]; + char s[256]; + + for (i = 0; i < 128; i++) + a[i] = (i+1) & 127; + for (i = 0; i < 256; i++) + *((unsigned char*)s+i) = i+1; + + T("", "", 0) + T("a", "", 1) + T("", "a", 0) + T("abc", "cde", 2) + T("abc", "ccc", 2) + T("abc", a, 0) + T("\xff\x80 abc", a, 2) + T(s, "\xff", 254) + + printf("%s finished\n", __FILE__); + return t_status; +} diff --git a/programs/develop/ktcc/trunk/libctest/string_strstr.c b/programs/develop/ktcc/trunk/libctest/string_strstr.c new file mode 100644 index 0000000000..a497f77871 --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/string_strstr.c @@ -0,0 +1,57 @@ +#include +#include +#include "test.h" + +#define N(s, sub) { \ + char *p = s; \ + char *q = strstr(p, sub); \ + if (q) \ + t_error("strstr(%s,%s) returned str+%d, wanted 0\n", #s, #sub, q-p); \ +} + +#define T(s, sub, n) { \ + char *p = s; \ + char *q = strstr(p, sub); \ + if (q == 0) \ + t_error("strstr(%s,%s) returned 0, wanted str+%d\n", #s, #sub, n); \ + else if (q - p != n) \ + t_error("strstr(%s,%s) returned str+%d, wanted str+%d\n", #s, #sub, q-p, n); \ +} + +int main(void) +{ + N("", "a") + N("a", "aa") + N("a", "b") + N("aa", "ab") + N("aa", "aaa") + N("abba", "aba") + N("abc abc", "abcd") + N("0-1-2-3-4-5-6-7-8-9", "-3-4-56-7-8-") + N("0-1-2-3-4-5-6-7-8-9", "-3-4-5+6-7-8-") + N("_ _ _\xff_ _ _", "_\x7f_") + N("_ _ _\x7f_ _ _", "_\xff_") + + T("", "", 0) + T("abcd", "", 0) + T("abcd", "a", 0) + T("abcd", "b", 1) + T("abcd", "c", 2) + T("abcd", "d", 3) + T("abcd", "ab", 0) + T("abcd", "bc", 1) + T("abcd", "cd", 2) + T("ababa", "baba", 1) + T("ababab", "babab", 1) + T("abababa", "bababa", 1) + T("abababab", "bababab", 1) + T("ababababa", "babababa", 1) + T("nanabanabanana", "aba", 3) + T("nanabanabanana", "ban", 4) + T("nanabanabanana", "anab", 1) + T("nanabanabanana", "banana", 8) + T("_ _\xff_ _", "_\xff_", 2) + + printf("%s finished\n", __FILE__); + return t_status; +} diff --git a/programs/develop/ktcc/trunk/libctest/strtod.c b/programs/develop/ktcc/trunk/libctest/strtod.c new file mode 100644 index 0000000000..43a30724ee --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/strtod.c @@ -0,0 +1,77 @@ +#include +#include +#include +#include "test.h" + +#define length(x) (sizeof(x) / sizeof *(x)) + +static struct { + char *s; + double f; +} t[] = { + {"0", 0.0}, + {"00.00", 0.0}, + {"-.00000", -0.0}, + {"1e+1000000", INFINITY}, + {"1e-1000000", 0}, + // 2^-1074 * 0.5 - eps + {".2470328229206232720882843964341106861825299013071623822127928412503377536351043e-323", 0}, + // 2^-1074 * 0.5 + eps + {".2470328229206232720882843964341106861825299013071623822127928412503377536351044e-323", 0x1p-1074}, + // 2^-1074 * 1.5 - eps + {".7410984687618698162648531893023320585475897039214871466383785237510132609053131e-323", 0x1p-1074}, + // 2^-1074 * 1.5 + eps + {".7410984687618698162648531893023320585475897039214871466383785237510132609053132e-323", 0x1p-1073}, + // 2^-1022 + 2^-1075 - eps + {".2225073858507201630123055637955676152503612414573018013083228724049586647606759e-307", 0x1p-1022}, + // 2^-1022 + 2^-1075 + eps + {".2225073858507201630123055637955676152503612414573018013083228724049586647606760e-307", 0x1.0000000000001p-1022}, + // 2^1024 - 2^970 - eps + {"17976931348623158079372897140530341507993413271003782693617377898044" + "49682927647509466490179775872070963302864166928879109465555478519404" + "02630657488671505820681908902000708383676273854845817711531764475730" + "27006985557136695962284291481986083493647529271907416844436551070434" + "2711559699508093042880177904174497791.999999999999999999999999999999", 0x1.fffffffffffffp1023}, + // 2^1024 - 2^970 + {"17976931348623158079372897140530341507993413271003782693617377898044" + "49682927647509466490179775872070963302864166928879109465555478519404" + "02630657488671505820681908902000708383676273854845817711531764475730" + "27006985557136695962284291481986083493647529271907416844436551070434" + "2711559699508093042880177904174497792", INFINITY}, + // some random numbers + {".5961860348131807091861002266453941950428e00", 0.59618603481318067}, // 0x1.313f4bc3b584cp-1 + {"1.815013169218038729887460898733526957442e-1", 0.18150131692180388}, // 0x1.73b6f662e1712p-3 + {"42.07082357534453600681618685682257590772e-2", 0.42070823575344535}, // 0x1.aece23c6e028dp-2 + {"665.4686306516261456328973225579833470816e-3", 0.66546863065162609}, // 0x1.54b84dea53453p-1 + {"6101.852922970868621786690495485449831753e-4", 0.61018529229708685}, // 0x1.386a34e5d516bp-1 + {"76966.95208236968077849464348875471158549e-5", 0.76966952082369677}, // 0x1.8a121f9954dfap-1 + {"250506.5322228682496132604807222923702304e-6", 0.25050653222286823}, // 0x1.0084c8cd538c2p-2 + {"2740037.230228005325852424697698331177377e-7", 0.27400372302280052}, // 0x1.18946e9575ef4p-2 + {"20723093.50049742645941529268715428324490e-8", 0.20723093500497428}, // 0x1.a868b14486e4dp-3 + {"0.7900280238081604956226011047460238748912e1", 7.9002802380816046}, // 0x1.f99e3100f2eaep+2 + {"0.9822860653737296848190558448760465863597e2", 98.228606537372968}, // 0x1.88ea17d506accp+6 + {"0.7468949723190370809405570560160405324869e3", 746.89497231903704}, // 0x1.75728e73f48b7p+9 + {"0.1630268320282728475980459844271031751665e4", 1630.2683202827284}, // 0x1.97912c28d5cbp+10 + {"0.4637168629719170695109918769645492022088e5", 46371.686297191707}, // 0x1.6a475f6258737p+15 + {"0.6537805944497711554209461686415872067523e6", 653780.59444977110}, // 0x1.3f3a9305bb86cp+19 + {"0.2346324356502437045212230713960457676531e6", 234632.43565024371}, // 0x1.ca4437c3631eap+17 + {"0.9709481716420048341897258980454298205278e8", 97094817.164200485}, // 0x1.7263284a8242cp+26 + {"0.4996908522051874110779982354932499499602e9", 499690852.20518744}, // 0x1.dc8ad6434872ap+28 +}; + +int main(void) +{ + int i; + double x; + char *p; + + for (i = 0; i < length(t); i++) { + x = strtod(t[i].s, &p); + if (x != t[i].f) + t_error("strtod(\"%s\") want %a got %a\n", t[i].s, t[i].f, x); + } + + printf("%s finished\n", __FILE__); + return t_status; +} + diff --git a/programs/develop/ktcc/trunk/libctest/strtod_long.c b/programs/develop/ktcc/trunk/libctest/strtod_long.c new file mode 100644 index 0000000000..a6aa777add --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/strtod_long.c @@ -0,0 +1,21 @@ +#include +#include +#include +#include "test.h" + +int main(void) +{ + double x, want = .1111111111111111111111; + char buf[40000]; + + memset(buf, '1', sizeof buf); + buf[0] = '.'; + buf[sizeof buf - 1] = 0; + + if ((x=strtod(buf, 0)) != want) + t_error("strtod(.11[...]1) got %a want %a\n", x, want); + + printf("%s finished\n", __FILE__); + return t_status; +} + diff --git a/programs/develop/ktcc/trunk/libctest/strtod_simple.c b/programs/develop/ktcc/trunk/libctest/strtod_simple.c new file mode 100644 index 0000000000..851a5218bd --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/strtod_simple.c @@ -0,0 +1,34 @@ +#include +#include +#include +#include "test.h" + +/* r = place to store result + * f = function call to test (or any expression) + * x = expected result + * m = message to print on failure (with formats for r & x) + */ + +#define TEST(r, f, x, m) ( \ + ((r) = (f)) == (x) || \ + (t_error("%s failed (" m ")\n", #f, r, x, r-x), 0) ) + +int main(void) +{ + int i; + double d, d2; + char buf[1000]; + + for (i=0; i<100; i++) { + d = sin(i); + snprintf(buf, sizeof buf, "%.300f", d); + TEST(d2, strtod(buf, 0), d, "round trip fail %a != %a (%a)"); + } + + TEST(d, strtod("0x1p4", 0), 16.0, "hex float %a != %a"); + TEST(d, strtod("0x1.1p4", 0), 17.0, "hex float %a != %a"); + + printf("%s finished\n", __FILE__); + return t_status; +} + diff --git a/programs/develop/ktcc/trunk/libctest/strtof.c b/programs/develop/ktcc/trunk/libctest/strtof.c new file mode 100644 index 0000000000..4b01477b85 --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/strtof.c @@ -0,0 +1,44 @@ +#include +#include +#include +#include "test.h" + +#define length(x) (sizeof(x) / sizeof *(x)) + +static struct { + char *s; + float f; +} t[] = { + // 2^-149 * 0.5 - eps + {".7006492321624085354618647916449580656401309709382578858785341419448955413429303e-45", 0}, + // 2^-149 * 0.5 + eps + {".7006492321624085354618647916449580656401309709382578858785341419448955413429304e-45", 0x1p-149}, + // 2^-149 * 0.5 - eps + {".2101947696487225606385594374934874196920392912814773657635602425834686624028790e-44", 0x1p-149}, + // 2^-149 * 0.5 + eps + {".2101947696487225606385594374934874196920392912814773657635602425834686624028791e-44", 0x1p-148}, + // 2^-126 + 2^-150 - eps + {".1175494420887210724209590083408724842314472120785184615334540294131831453944281e-37", 0x1p-126}, + // 2^-126 + 2^-150 + eps + {".1175494420887210724209590083408724842314472120785184615334540294131831453944282e-37", 0x1.000002p-126}, + // 2^128 - 2^103 - eps + {"340282356779733661637539395458142568447.9999999999999999999", 0x1.fffffep127}, + // 2^128 - 2^103 + {"340282356779733661637539395458142568448", INFINITY}, +}; + +int main(void) +{ + int i; + float x; + char *p; + + for (i = 0; i < length(t); i++) { + x = strtof(t[i].s, &p); + if (x != t[i].f) + t_error("strtof(\"%s\") want %a got %a\n", t[i].s, t[i].f, x); + } + + printf("%s finished\n", __FILE__); + return t_status; +} diff --git a/programs/develop/ktcc/trunk/libctest/strtol.c b/programs/develop/ktcc/trunk/libctest/strtol.c new file mode 100644 index 0000000000..f4d8089863 --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/strtol.c @@ -0,0 +1,80 @@ +#include +#include +#include +//#include +#include "test.h" + +/* r = place to store result + * f = function call to test (or any expression) + * x = expected result + * m = message to print on failure (with formats for r & x) +**/ + +#define TEST(r, f, x, m) ( \ + errno = 0, msg = #f, ((r) = (f)) == (x) || \ + (t_error("%s failed (" m ")\n", #f, r, x), 0) ) + +#define TEST2(r, f, x, m) ( \ + ((r) = (f)) == (x) || \ + (t_error("%s failed (" m ")\n", msg, r, x), 0) ) + +int main(void) +{ + int i; + long l; + unsigned long ul; + char *msg=""; + char *s, *c; + + TEST(l, atol("2147483647"), 2147483647L, "max 32bit signed %ld != %ld"); + TEST(l, strtol("2147483647", 0, 0), 2147483647L, "max 32bit signed %ld != %ld"); + TEST(ul, strtoul("4294967295", 0, 0), 4294967295UL, "max 32bit unsigned %lu != %lu"); + + if (sizeof(long) == 4) { + TEST(l, strtol(s="2147483648", &c, 0), 2147483647L, "uncaught overflow %ld != %ld"); + TEST2(i, c-s, 10, "wrong final position %d != %d"); + TEST2(i, errno, ERANGE, "missing errno %d != %d"); + TEST(l, strtol(s="-2147483649", &c, 0), -2147483647L-1, "uncaught overflow %ld != %ld"); + TEST2(i, c-s, 11, "wrong final position %d != %d"); + TEST2(i, errno, ERANGE, "missing errno %d != %d"); + TEST(ul, strtoul(s="4294967296", &c, 0), 4294967295UL, "uncaught overflow %lu != %lu"); + TEST2(i, c-s, 10, "wrong final position %d != %d"); + TEST2(i, errno, ERANGE, "missing errno %d != %d"); + TEST(ul, strtoul(s="-1", &c, 0), -1UL, "rejected negative %lu != %lu"); + TEST2(i, c-s, 2, "wrong final position %d != %d"); + TEST2(i, errno, 0, "spurious errno %d != %d"); + TEST(ul, strtoul(s="-2", &c, 0), -2UL, "rejected negative %lu != %lu"); + TEST2(i, c-s, 2, "wrong final position %d != %d"); + TEST2(i, errno, 0, "spurious errno %d != %d"); + TEST(ul, strtoul(s="-2147483648", &c, 0), -2147483648UL, "rejected negative %lu != %lu"); + TEST2(i, c-s, 11, "wrong final position %d != %d"); + TEST2(i, errno, 0, "spurious errno %d != %d"); + TEST(ul, strtoul(s="-2147483649", &c, 0), -2147483649UL, "rejected negative %lu != %lu"); + TEST2(i, c-s, 11, "wrong final position %d != %d"); + TEST2(i, errno, 0, "spurious errno %d != %d"); + } else { + TEST(i, 0, 1, "64bit tests not implemented"); + } + + TEST(l, strtol("z", 0, 36), 35, "%ld != %ld"); + TEST(l, strtol("00010010001101000101011001111000", 0, 2), 0x12345678, "%ld != %ld"); + TEST(l, strtol(s="0F5F", &c, 16), 0x0f5f, "%ld != %ld"); + + TEST(l, strtol(s="0xz", &c, 16), 0, "%ld != %ld"); + TEST2(i, c-s, 1, "wrong final position %ld != %ld"); + + TEST(l, strtol(s="0x1234", &c, 16), 0x1234, "%ld != %ld"); + TEST2(i, c-s, 6, "wrong final position %ld != %ld"); + + c = NULL; + TEST(l, strtol(s="123", &c, 37), 0, "%ld != %ld"); + TEST2(i, c-s, 0, "wrong final position %d != %d"); + TEST2(i, errno, EINVAL, "%d != %d"); + + TEST(l, strtol(s=" 15437", &c, 8), 015437, "%ld != %ld"); + TEST2(i, c-s, 7, "wrong final position %d != %d"); + + TEST(l, strtol(s=" 1", &c, 0), 1, "%ld != %ld"); + TEST2(i, c-s, 3, "wrong final position %d != %d"); + return t_status; +} diff --git a/programs/develop/ktcc/trunk/libctest/strtold.c b/programs/develop/ktcc/trunk/libctest/strtold.c new file mode 100644 index 0000000000..7e50d5eae9 --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/strtold.c @@ -0,0 +1,96 @@ +#include +#include +#include +#include +#include "test.h" + +#define length(x) (sizeof(x) / sizeof *(x)) + +static struct { + char *s; + long double f; +} t[] = { + {"0", 0.0}, + {"12.345", 12.345L}, + {"1.2345e1", 12.345L}, + {"1e+1000000", INFINITY}, + {"1e-1000000", 0}, +#if LDBL_MANT_DIG == 53 + // 2^-1074 * 0.5 - eps + {".2470328229206232720882843964341106861825299013071623822127928412503377536351043e-323", 0}, + // 2^-1074 * 0.5 + eps + {".2470328229206232720882843964341106861825299013071623822127928412503377536351044e-323", 0x1p-1074}, + // 2^-1074 * 1.5 - eps + {".7410984687618698162648531893023320585475897039214871466383785237510132609053131e-323", 0x1p-1074}, + // 2^-1074 * 1.5 + eps + {".7410984687618698162648531893023320585475897039214871466383785237510132609053132e-323", 0x1p-1073}, + // 2^-1022 + 2^-1075 - eps + {".2225073858507201630123055637955676152503612414573018013083228724049586647606759e-307", 0x1p-1022}, + // 2^-1022 + 2^-1075 + eps + {".2225073858507201630123055637955676152503612414573018013083228724049586647606760e-307", 0x1.0000000000001p-1022}, + // 2^1024 - 2^970 - eps + {"17976931348623158079372897140530341507993413271003782693617377898044" + "49682927647509466490179775872070963302864166928879109465555478519404" + "02630657488671505820681908902000708383676273854845817711531764475730" + "27006985557136695962284291481986083493647529271907416844436551070434" + "2711559699508093042880177904174497791.999999999999999999999999999999", 0x1.fffffffffffffp1023}, + // 2^1024 - 2^970 + {"17976931348623158079372897140530341507993413271003782693617377898044" + "49682927647509466490179775872070963302864166928879109465555478519404" + "02630657488671505820681908902000708383676273854845817711531764475730" + "27006985557136695962284291481986083493647529271907416844436551070434" + "2711559699508093042880177904174497792", INFINITY}, + // some random numbers + {".5961860348131807091861002266453941950428e00", 0.59618603481318067}, // 0x1.313f4bc3b584cp-1 + {"1.815013169218038729887460898733526957442e-1", 0.18150131692180388}, // 0x1.73b6f662e1712p-3 + {"42.07082357534453600681618685682257590772e-2", 0.42070823575344535}, // 0x1.aece23c6e028dp-2 + {"665.4686306516261456328973225579833470816e-3", 0.66546863065162609}, // 0x1.54b84dea53453p-1 + {"6101.852922970868621786690495485449831753e-4", 0.61018529229708685}, // 0x1.386a34e5d516bp-1 + {"76966.95208236968077849464348875471158549e-5", 0.76966952082369677}, // 0x1.8a121f9954dfap-1 + {"250506.5322228682496132604807222923702304e-6", 0.25050653222286823}, // 0x1.0084c8cd538c2p-2 + {"2740037.230228005325852424697698331177377e-7", 0.27400372302280052}, // 0x1.18946e9575ef4p-2 + {"20723093.50049742645941529268715428324490e-8", 0.20723093500497428}, // 0x1.a868b14486e4dp-3 + {"0.7900280238081604956226011047460238748912e1", 7.9002802380816046}, // 0x1.f99e3100f2eaep+2 + {"0.9822860653737296848190558448760465863597e2", 98.228606537372968}, // 0x1.88ea17d506accp+6 + {"0.7468949723190370809405570560160405324869e3", 746.89497231903704}, // 0x1.75728e73f48b7p+9 + {"0.1630268320282728475980459844271031751665e4", 1630.2683202827284}, // 0x1.97912c28d5cbp+10 + {"0.4637168629719170695109918769645492022088e5", 46371.686297191707}, // 0x1.6a475f6258737p+15 + {"0.6537805944497711554209461686415872067523e6", 653780.59444977110}, // 0x1.3f3a9305bb86cp+19 + {"0.2346324356502437045212230713960457676531e6", 234632.43565024371}, // 0x1.ca4437c3631eap+17 + {"0.9709481716420048341897258980454298205278e8", 97094817.164200485}, // 0x1.7263284a8242cp+26 + {"0.4996908522051874110779982354932499499602e9", 499690852.20518744}, // 0x1.dc8ad6434872ap+28 +#elif LDBL_MANT_DIG == 64 + // 2^-16445 * 0.5 - eps + {".1822599765941237301264202966809709908199525407846781671860490243514185844316698e-4950", 0}, + // 2^-16445 * 0.5 + eps + {".1822599765941237301264202966809709908199525407846781671860490243514185844316699e-4950", 0x1p-16445L}, + // 2^-16445 * 1.5 - eps + {".5467799297823711903792608900429129724598576223540345015581470730542557532950096e-4950", 0x1p-16445L}, + // 2^-16445 * 1.5 + eps + {".5467799297823711903792608900429129724598576223540345015581470730542557532950097e-4950", 0x1p-16444L}, + // 2^-16382 + 2^-16446 - eps + {".3362103143112093506444937793915876332724499641527442230928779770593420866576777e-4931", 0x1p-16382L}, + // 2^-16382 + 2^-16446 + eps + {".3362103143112093506444937793915876332724499641527442230928779770593420866576778e-4931", 0x1.0000000000000002p-16382L}, + // 2^16384 - 2^16319 - eps + {"118973149535723176505351158982948.86679662540046955672e4900", 0x1.fffffffffffffffep16383L}, + // 2^16384 - 2^16319 + eps + {"118973149535723176505351158982948.86679662540046955673e4900", INFINITY}, +#endif +}; + +int main(void) +{ + int i; + long double x; + char *p; + + for (i = 0; i < length(t); i++) { + x = strtold(t[i].s, &p); + if (x != t[i].f) + t_error("strtold(\"%s\") want %La got %La\n", t[i].s, t[i].f, x); + } + + printf("%s finished\n", __FILE__); + return t_status; +} diff --git a/programs/develop/ktcc/trunk/libctest/test.h b/programs/develop/ktcc/trunk/libctest/test.h new file mode 100644 index 0000000000..0168fc262f --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/test.h @@ -0,0 +1,37 @@ +#include +#include +#ifdef __GNUC__ +#include +#include +#include +#include +#endif + + +/* TODO: not thread-safe nor fork-safe */ +extern volatile int t_status; + +#define T_LOC2(l) __FILE__ ":" #l +#define T_LOC1(l) T_LOC2(l) +#define t_error(...) t_printf(T_LOC1(__LINE__) ": " __VA_ARGS__) + +int t_printf(const char *s, ...); + +int t_vmfill(void **, size_t *, int); +int t_memfill(void); + +void t_fdfill(void); + +void t_randseed(uint64_t s); +uint64_t t_randn(uint64_t n); +uint64_t t_randint(uint64_t a, uint64_t b); +void t_shuffle(uint64_t *p, size_t n); +void t_randrange(uint64_t *p, size_t n); +int t_choose(uint64_t n, size_t k, uint64_t *p); + +char *t_pathrel(char *buf, size_t n, char *argv0, char *p); + +int t_setrlim(int r, long lim); + +#include "print.inc" +#include "rand.inc" diff --git a/programs/develop/ktcc/trunk/libctest/tgmath.c b/programs/develop/ktcc/trunk/libctest/tgmath.c new file mode 100644 index 0000000000..09265be916 --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/tgmath.c @@ -0,0 +1,41 @@ +//#include +#include +#include +#include "test.h" + +int main(void) +{ + long i; +/* + i = lrint(123456789.1f) & 0x7fffffff; + if (i != 123456792) + t_error("lrint(123456789.1f)&0x7fffffff want 123456792 got %ld\n", i); + i = lrint(123456789.1) & 0x7fffffff; + if (i != 123456789) + t_error("lrint(123456789.1)&0x7fffffff want 123456789 got %ld\n", i); +*/ + if (sqrt(2.0f) != 1.41421353816986083984375) + t_error("sqrt(2.0f) want 1.41421353816986083984375 got %f\n", sqrt(2.0f)); + if (sqrt(2.0) != 1.414213562373095145474621858738828450441360) + t_error("sqrt(2.0) want 1.414213562373095145474621858738828450441360 got %d\n", sqrt(2.0)); + if (sqrt(2) != 1.414213562373095145474621858738828450441360) + t_error("sqrt(2) want 0x1.6a09e667f3bcdp+0 got %a\n", sqrt(2.0)); + + if (sizeof pow(sqrt(8),0.5f) != sizeof(double)) + t_error("sizeof pow(sqrt(8),0.5f) want %d got %d\n", (int)sizeof(double), (int)sizeof pow(sqrt(8),0.5f)); + if (sizeof pow(2.0,0.5) != sizeof(double)) + t_error("sizeof pow(2.0,0.5) want %d got %d\n", (int)sizeof(double), (int)sizeof pow(2.0,0.5)); + if (sizeof pow(2.0f,0.5f) != sizeof(float)) + t_error("sizeof pow(2.0f,0.5f) want %d got %d\n", (int)sizeof(float), (int)sizeof pow(2.0f,0.5f)); +// if (sizeof pow(2.0,0.5+0*I) != sizeof(double complex)) +// t_error("sizeof pow(2.0,0.5+0*I) want %d got %d\n", (int)sizeof(double complex), (int)sizeof pow(2.0,0.5+0*I)); + + if (pow(2.0,0.5) != 1.414213562373095145474621858738828450441360) + t_error("pow(2.0,0.5) want 0x1.6a09e667f3bcdp+0 got %a\n", pow(2.0,0.5)); + if (pow(2,0.5) != 1.414213562373095145474621858738828450441360) + t_error("pow(2,0.5) want 0x1.6a09e667f3bcdp+0 got %a\n", pow(2,0.5)); + if (pow(2,0.5f) != 1.414213562373095145474621858738828450441360) + t_error("pow(2,0.5f) want 0x1.6a09e667f3bcdp+0 got %a\n", pow(2,0.5f)); + + return t_status; +} diff --git a/programs/develop/ktcc/trunk/libctest/time.c b/programs/develop/ktcc/trunk/libctest/time.c new file mode 100644 index 0000000000..0b22dfc12c --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/time.c @@ -0,0 +1,110 @@ +#define _XOPEN_SOURCE 700 +#include +#include +#include +#include +#include +#include +#include "test.h" + +/* We use this instead of memcmp because some broken C libraries + * add additional nonstandard fields to struct tm... */ + +int tm_cmp(struct tm tm1, struct tm tm2) +{ + return tm1.tm_sec != tm2.tm_sec || + tm1.tm_min != tm2.tm_min || + tm1.tm_hour != tm2.tm_hour || + tm1.tm_mday != tm2.tm_mday || + tm1.tm_mon != tm2.tm_mon || + tm1.tm_year != tm2.tm_year || + tm1.tm_wday != tm2.tm_wday || + tm1.tm_yday != tm2.tm_yday || + tm1.tm_isdst!= tm2.tm_isdst; +} + +char *tm_str(struct tm tm) +{ + static int i; + static char b[4][64]; + i = (i+1)%4; + snprintf(b[i], sizeof b[i], + "s=%02d m=%02d h=%02d mday=%02d mon=%02d year=%04d wday=%d yday=%d isdst=%d", + tm.tm_sec, tm.tm_min, tm.tm_hour, + tm.tm_mday, tm.tm_mon, tm.tm_year, + tm.tm_wday, tm.tm_yday, tm.tm_isdst); + return b[i]; +} + +#define TM(ss,mm,hh,md,mo,yr,wd,yd,dst) (struct tm){ \ + .tm_sec = ss, .tm_min = mm, .tm_hour = hh, \ + .tm_mday = md, .tm_mon = mo, .tm_year = yr, \ + .tm_wday = wd, .tm_yday = yd, .tm_isdst = dst } + +#define TM_EPOCH TM(0,0,0,1,0,70,4,0,0) +#define TM_Y2038_1S TM(7,14,3,19,0,138,2,18,0) +#define TM_Y2038 TM(8,14,3,19,0,138,2,18,0) + +static void sec2tm(time_t t, char *m) +{ + struct tm *tm; + time_t r; + + errno = 0; + tm = gmtime(&t); + if (errno != 0) + t_error("%s: gmtime((time_t)%lld) should not set errno, got %s\n", + m, (long long)t, strerror(errno)); + errno = 0; + r = mktime(tm); + if (errno != 0) + t_error("%s: mktime(%s) should not set errno, got %s\n", + m, tm_str(*tm), strerror(errno)); + if (t != r) + t_error("%s: mktime(gmtime(%lld)) roundtrip failed: got %lld (gmtime is %s)\n", + m, (long long)t, (long long)r, tm_str(*tm)); +} + +static void tm2sec(struct tm *tm, int big, char *m) +{ + struct tm *r; + time_t t; + int overflow = big && (time_t)LLONG_MAX!=LLONG_MAX; + + errno = 0; + t = mktime(tm); + if (overflow && t != -1) + t_error("%s: mktime(%s) expected -1, got (time_t)%ld\n", + m, tm_str(*tm), (long)t); + if (overflow && errno != 10000) //EOVERFLOW + t_error("%s: mktime(%s) expected EOVERFLOW (%s), got (%s)\n", + m, tm_str(*tm), strerror(10000), strerror(errno)); + if (!overflow && t == -1) + t_error("%s: mktime(%s) expected success, got (time_t)-1\n", + m, tm_str(*tm)); + if (!overflow && errno) + t_error("%s: mktime(%s) expected no error, got (%s)\n", + m, tm_str(*tm), strerror(errno)); + r = gmtime(&t); + if (!overflow && tm_cmp(*r, *tm)) + t_error("%s: gmtime(mktime(%s)) roundtrip failed: got %s\n", + m, tm_str(*tm), tm_str(*r)); +} + +int main(void) +{ + time_t t; + + putenv("TZ=GMT"); + tzset(); + tm2sec(&TM_EPOCH, 0, "gmtime(0)"); + tm2sec(&TM_Y2038_1S, 0, "2038-1s"); + tm2sec(&TM_Y2038, 1, "2038"); + + sec2tm(0, "EPOCH"); + for (t = 1; t < 1000; t++) + sec2tm(t*100003, "EPOCH+eps"); + + /* FIXME: set a TZ var and check DST boundary conditions */ + return t_status; +} diff --git a/programs/develop/ktcc/trunk/libctest/tstring.c b/programs/develop/ktcc/trunk/libctest/tstring.c new file mode 100644 index 0000000000..6d9eaf8ea7 --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/tstring.c @@ -0,0 +1,354 @@ +/* + * Copyright (C) 2002 by Red Hat, Incorporated. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software + * is freely granted, provided that this notice is preserved. + */ + +#include +#include +#include + +#ifndef MAX_1 +#ifdef __SPU__ +#define MAX_1 11000 +#else +#define MAX_1 33000 +#endif +#endif + +#define MAX_2 (2 * MAX_1 + MAX_1 / 10) + +void eprintf (int line, char *result, char *expected, int size) +{ + if (size != 0) + printf ("Failure at line %d, result is <%.*s>, should be <%s> of size %d\n", + line, size, result, expected, size); + else + printf ("Failure at line %d, result is <%s>, should be <%s>\n", + line, result, expected); +} + +void mycopy (char *target, char *source, int size) +{ + int i; + + for (i = 0; i < size; ++i) + { + target[i] = source[i]; + } +} + +void myset (char *target, char ch, int size) +{ + int i; + + for (i = 0; i < size; ++i) + { + target[i] = ch; + } +} + +int main() +{ + char target[MAX_1] = "A"; + char first_char; + char second_char; + char array[] = "abcdefghijklmnopqrstuvwxz"; + char array2[] = "0123456789!@#$%^&*("; + char buffer2[MAX_1]; + char buffer3[MAX_1]; + char buffer4[MAX_1]; + char buffer5[MAX_2]; + char buffer6[MAX_2]; + char buffer7[MAX_2]; + char expected[MAX_1]; + char *tmp1, *tmp2, *tmp3, *tmp4, *tmp5, *tmp6, *tmp7; + int i, j, k, x, z, align_test_iterations; + + int test_failed = 0; + + tmp1 = target; + tmp2 = buffer2; + tmp3 = buffer3; + tmp4 = buffer4; + tmp5 = buffer5; + tmp6 = buffer6; + tmp7 = buffer7; + + tmp2[0] = 'Z'; + tmp2[1] = '\0'; + + if (memset (target, 'X', 0) != target || + memcpy (target, "Y", 0) != target || + memmove (target, "K", 0) != target || + strncpy (tmp2, "4", 0) != tmp2 || + strncat (tmp2, "123", 0) != tmp2 || + strcat (target, "") != target) + { + eprintf (__LINE__, target, "A", 0); + test_failed = 1; + } + + if (strcmp (target, "A") || strlen(target) != 1 || memchr (target, 'A', 0) != NULL + || memcmp (target, "J", 0) || strncmp (target, "A", 1) || strncmp (target, "J", 0) || + tmp2[0] != 'Z' || tmp2[1] != '\0') + { + eprintf (__LINE__, target, "A", 0); + test_failed = 1; + } + + tmp2[2] = 'A'; + if (strcpy (target, "") != target || + strncpy (tmp2, "", 4) != tmp2 || + strcat (target, "") != target) + { + eprintf (__LINE__, target, "", 0); + test_failed = 1; + } + + if (target[0] != '\0' || strncmp (target, "", 1) || + memcmp (tmp2, "\0\0\0\0", 4)) + { + eprintf (__LINE__, target, "", 0); + test_failed = 1; + } + + tmp2[2] = 'A'; + if (strncat (tmp2, "1", 3) != tmp2 || + memcmp (tmp2, "1\0A", 3)) + { + eprintf (__LINE__, tmp2, "1\0A", 3); + test_failed = 1; + } + + if (strcpy (tmp3, target) != tmp3 || + strcat (tmp3, "X") != tmp3 || + strncpy (tmp2, "X", 2) != tmp2 || + memset (target, tmp2[0], 1) != target) + { + eprintf (__LINE__, target, "X", 0); + test_failed = 1; + } + + if (strcmp (target, "X") || strlen (target) != 1 || + memchr (target, 'X', 2) != target || + strchr (target, 'X') != target || + memchr (target, 'Y', 2) != NULL || + strchr (target, 'Y') != NULL || + strcmp (tmp3, target) || + strncmp (tmp3, target, 2) || + memcmp (target, "K", 0) || + strncmp (target, tmp3, 3)) + { + eprintf (__LINE__, target, "X", 0); + test_failed = 1; + } + + if (strcpy (tmp3, "Y") != tmp3 || + strcat (tmp3, "Y") != tmp3 || + memset (target, 'Y', 2) != target) + { + eprintf (__LINE__, target, "Y", 0); + test_failed = 1; + } + + target[2] = '\0'; + if (memcmp (target, "YY", 2) || strcmp (target, "YY") || + strlen (target) != 2 || memchr (target, 'Y', 2) != target || + strcmp (tmp3, target) || + strncmp (target, tmp3, 3) || + strncmp (target, tmp3, 4) || + strncmp (target, tmp3, 2) || + strchr (target, 'Y') != target) + { + eprintf (__LINE__, target, "YY", 2); + test_failed = 1; + } + + strcpy (target, "WW"); + if (memcmp (target, "WW", 2) || strcmp (target, "WW") || + strlen (target) != 2 || memchr (target, 'W', 2) != target || + strchr (target, 'W') != target) + { + eprintf (__LINE__, target, "WW", 2); + test_failed = 1; + } + + if (strncpy (target, "XX", 16) != target || + memcmp (target, "XX\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16)) + { + eprintf (__LINE__, target, "XX\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16); + test_failed = 1; + } + + if (strcpy (tmp3, "ZZ") != tmp3 || + strcat (tmp3, "Z") != tmp3 || + memcpy (tmp4, "Z", 2) != tmp4 || + strcat (tmp4, "ZZ") != tmp4 || + memset (target, 'Z', 3) != target) + { + eprintf (__LINE__, target, "ZZZ", 3); + test_failed = 1; + } + + target[3] = '\0'; + tmp5[0] = '\0'; + strncat (tmp5, "123", 2); + if (memcmp (target, "ZZZ", 3) || strcmp (target, "ZZZ") || + strcmp (tmp3, target) || strcmp (tmp4, target) || + strncmp (target, "ZZZ", 4) || strncmp (target, "ZZY", 3) <= 0 || + strncmp ("ZZY", target, 4) >= 0 || + memcmp (tmp5, "12", 3) || + strlen (target) != 3) + { + eprintf (__LINE__, target, "ZZZ", 3); + test_failed = 1; + } + + target[2] = 'K'; + if (memcmp (target, "ZZZ", 2) || strcmp (target, "ZZZ") >= 0 || + memcmp (target, "ZZZ", 3) >= 0 || strlen (target) != 3 || + memchr (target, 'K', 3) != target + 2 || + strncmp (target, "ZZZ", 2) || strncmp (target, "ZZZ", 4) >= 0 || + strchr (target, 'K') != target + 2) + { + eprintf (__LINE__, target, "ZZK", 3); + test_failed = 1; + } + + strcpy (target, "AAA"); + if (memcmp (target, "AAA", 3) || strcmp (target, "AAA") || + strncmp (target, "AAA", 3) || + strlen (target) != 3) + { + eprintf (__LINE__, target, "AAA", 3); + test_failed = 1; + } + + j = 5; + while (j < MAX_1) + { + for (i = j-1; i <= j+1; ++i) + { + /* don't bother checking unaligned data in the larger + sizes since it will waste time without performing additional testing */ + if (i <= 16 * sizeof(long)) + { + align_test_iterations = 2*sizeof(long); + if (i <= 2 * sizeof(long) + 1) + z = 2; + else + z = 2 * sizeof(long); + } + else + { + align_test_iterations = 1; + } + + for (x = 0; x < align_test_iterations; ++x) + { + tmp1 = target + x; + tmp2 = buffer2 + x; + tmp3 = buffer3 + x; + tmp4 = buffer4 + x; + tmp5 = buffer5 + x; + tmp6 = buffer6 + x; + + first_char = array[i % (sizeof(array) - 1)]; + second_char = array2[i % (sizeof(array2) - 1)]; + memset (tmp1, first_char, i); + mycopy (tmp2, tmp1, i); + myset (tmp2 + z, second_char, i - z - 1); + if (memcpy (tmp1 + z, tmp2 + z, i - z - 1) != tmp1 + z) + { + printf ("error at line %d\n", __LINE__); + test_failed = 1; + } + + tmp1[i] = '\0'; + tmp2[i] = '\0'; + if (strcpy (expected, tmp2) != expected) + { + printf ("error at line %d\n", __LINE__); + test_failed = 1; + } + tmp2[i-z] = first_char + 1; + if (memmove (tmp2 + z + 1, tmp2 + z, i - z - 1) != tmp2 + z + 1 || + memset (tmp3, first_char, i) != tmp3) + { + printf ("error at line %d\n", __LINE__); + test_failed = 1; + } + + myset (tmp4, first_char, i); + tmp5[0] = '\0'; + if (strncpy (tmp5, tmp1, i+1) != tmp5 || + strcat (tmp5, tmp1) != tmp5) + { + printf ("error at line %d\n", __LINE__); + test_failed = 1; + } + mycopy (tmp6, tmp1, i); + mycopy (tmp6 + i, tmp1, i + 1); + + tmp7[2*i+z] = second_char; + strcpy (tmp7, tmp1); + + strchr (tmp1, second_char); + + if (memcmp (tmp1, expected, i) || strcmp (tmp1, expected) || + strncmp (tmp1, expected, i) || + strncmp (tmp1, expected, i+1) || + strcmp (tmp1, tmp2) >= 0 || memcmp (tmp1, tmp2, i) >= 0 || + strncmp (tmp1, tmp2, i+1) >= 0 || + strlen (tmp1) != i || memchr (tmp1, first_char, i) != tmp1 || + strchr (tmp1, first_char) != tmp1 || + memchr (tmp1, second_char, i) != tmp1 + z || + strchr (tmp1, second_char) != tmp1 + z || + strcmp (tmp5, tmp6) || + strncat (tmp7, tmp1, i+2) != tmp7 || + strcmp (tmp7, tmp6) || + tmp7[2*i+z] != second_char) + { + eprintf (__LINE__, tmp1, expected, 0); + printf ("x is %d\n",x); + printf ("i is %d\n", i); + printf ("tmp1 is <%p>\n", tmp1); + printf ("tmp5 is <%p> <%s>\n", tmp5, tmp5); + printf ("tmp6 is <%p> <%s>\n", tmp6, tmp6); + test_failed = 1; + } + + for (k = 1; k <= align_test_iterations && k <= i; ++k) + { + if (memcmp (tmp3, tmp4, i - k + 1) != 0 || + strncmp (tmp3, tmp4, i - k + 1) != 0) + { + printf ("Failure at line %d, comparing %.*s with %.*s\n", + __LINE__, i, tmp3, i, tmp4); + test_failed = 1; + } + tmp4[i-k] = first_char + 1; + if (memcmp (tmp3, tmp4, i) >= 0 || + strncmp (tmp3, tmp4, i) >= 0 || + memcmp (tmp4, tmp3, i) <= 0 || + strncmp (tmp4, tmp3, i) <= 0) + { + printf ("Failure at line %d, comparing %.*s with %.*s\n", + __LINE__, i, tmp3, i, tmp4); + test_failed = 1; + } + tmp4[i-k] = first_char; + } + } + } + j = ((2 * j) >> 2) << 2; + } + +printf("%s finished\n", __FILE__); + if (test_failed) + abort(); + else + exit(0); +} \ No newline at end of file diff --git a/programs/develop/ktcc/trunk/libctest/udiv.c b/programs/develop/ktcc/trunk/libctest/udiv.c new file mode 100644 index 0000000000..3522c6340f --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/udiv.c @@ -0,0 +1,170 @@ +#include "test.h" +//#include + +/* +static uint64_t randstate = 0x123456789abcdef0ull; +static uint64_t rnd(void) { + randstate = 6364136223846793005ull*randstate + 1; + return randstate; +} +void test_maketest() +{ + int i; + uint64_t x,y; + for (i = 0; i < 128; i++) { + x = rnd(); + y = rnd()>>(i/2); + if (!y) + continue; + printf("0x%llxull, 0x%llxull, 0x%llxull, 0x%llxull,\n", x, y, x/y, x%y); + } +} +*/ + +static struct { + uint64_t x, y, div, mod; +} t[] = { +0x8ddb1a43e77c4031ull, 0x5950e8c33d34979eull, 0x1ull, 0x348a3180aa47a893ull, +0x723f4114006c08c7ull, 0x817de530db2b43fcull, 0x0ull, 0x723f4114006c08c7ull, +0x47811fa5f00f74dull, 0x3d98e7d3fcd5d5c5ull, 0x0ull, 0x47811fa5f00f74dull, +0x51ffcc7cdc989d43ull, 0x36be8bd6746b70e4ull, 0x1ull, 0x1b4140a6682d2c5full, +0x57bf9128512fe829ull, 0x197b3858155d498dull, 0x3ull, 0xb4de82011180b82ull, +0x89fc1c5968fa817full, 0xdcea797734c7115ull, 0x9ull, 0xdb838065b4a87c2ull, +0x4ed5264cf7092ec5ull, 0xde40d1e15ef3e74ull, 0x5ull, 0x960e4b6895cf681ull, +0xffd86b253d97317bull, 0x13f9ff2d24b6d6f4ull, 0xcull, 0x1020750785051e0bull, +0x8771fa2da656a721ull, 0x9210fe654c59bfcull, 0xeull, 0x7a31b9503881f59ull, +0xb5961d12bcd3e937ull, 0xbdb5a33662f547aull, 0xfull, 0x3bbd40fc00df611ull, +0x93c79eecdac7ed3dull, 0x6f267c57ea2b7b5ull, 0x15ull, 0x1e51bb9776edb64ull, +0x6b93ffce49f1a4b3ull, 0x3583d1f9702ee03ull, 0x20ull, 0x8c5bdb6993e453ull, +0x138aefcc98ce5d19ull, 0x117002fa7600b11ull, 0x11ull, 0x103eca27b6da0f8ull, +0xb3da641cef491fefull, 0x357615f638334b8ull, 0x35ull, 0x2c33b5d551f35d7ull, +0x71c4b06e463912b5ull, 0x1c286ad9e8f5229ull, 0x40ull, 0x1230506a2648875ull, +0x97d4cf7df046d6ebull, 0x1e9412f5c77b2b8ull, 0x4full, 0xd9b1e06756b023ull, +0x1428f04bd490ea11ull, 0x9d97f29a897c93ull, 0x20ull, 0x75f1f8836157b1ull, +0x35256c76832705a7ull, 0xa962f1a447dcd7ull, 0x50ull, 0x3680f32cb20277ull, +0x2969e82bd9347f2dull, 0x723d68574d4156ull, 0x5cull, 0x5bd6ac79710445ull, +0x9061a12aae71a823ull, 0x4186d8a1a66175ull, 0x234ull, 0x48be68be2f25full, +0x695b8d33ef342e09ull, 0x3ed1fe1a998fe3ull, 0x1adull, 0x15a6615bde0ea2ull, +0x46b4dd1e06367a5full, 0xa04e70622e4e8ull, 0x70eull, 0x64750bc0b9dafull, +0xd68b05ba7eee12a5ull, 0x72ab3fb682444ull, 0x1defull, 0x3c437fc988329ull, +0x1e59cc2ac508f85bull, 0xeb15ae6d4d7f9ull, 0x210ull, 0xc00aeae0b86cbull, +0x296f8d2c76a0901ull, 0xf65628b31b01ull, 0x2b0ull, 0xf14566117651ull, +0x7036f5ad7cbc5e17ull, 0xa09d3bfcf72cfull, 0xb2dull, 0x72236db564ab4ull, +0x915d6883c575ad1dull, 0x3a38d68d3a38eull, 0x27f2ull, 0x241de6f7a6ee1ull, +0x845ba74f5adfa793ull, 0x2f6950e58d00bull, 0x2caaull, 0x249dc90239c45ull, +0xb910d16c54805af9ull, 0x1fc2ca5c99a7aull, 0x5d3aull, 0x1771487b50955ull, +0x27a2e280bcf990cfull, 0x389aa0c0b0cc0ull, 0xb34ull, 0x9d71d12eb9cfull, +0x1e032f04a5372e95ull, 0x63c2a1d58710ull, 0x4d04ull, 0x154ce4414255ull, +0x3a1a5659908495cbull, 0x279dcd85418aull, 0x17775ull, 0x132c6f9c7bb9ull, +0xd769a376e5e103f1ull, 0xadacb670e0c7ull, 0x13d85ull, 0x8ad256e5d18eull, +0x269f4f4baaaf287ull, 0x1aed2ad9daf0ull, 0x16f3ull, 0x426550f80b7ull, +0x6700daeeb87a770dull, 0xeca7ab1aa93ull, 0x6f6c5ull, 0x70d9466f1eeull, +0xd0201f3783c2a303ull, 0x3a0c01aa3e6aull, 0x395e1ull, 0x18b33b9015d9ull, +0xca3f2e00d291e3e9ull, 0xbe0e048cd94ull, 0x1106c2ull, 0x37f7fc0a1c1ull, +0xec4d240dc289633full, 0x4f8aadb7483ull, 0x2f8855ull, 0x46e0db91bc0ull, +0xd7967b29e2e36685ull, 0xe61d902db27ull, 0xefd69ull, 0x36811fff886ull, +0xe3ecd4374320af3bull, 0x4edd0edd0a0ull, 0x2e3defull, 0x4ad0da4c9dbull, +0x7a08fe1d98b4dae1ull, 0x6bced9c0c15ull, 0x121c89ull, 0x40c856617a4ull, +0x34435992a5c9c2f7ull, 0x4f4a94c109full, 0xa8bc9ull, 0x94c5d46120ull, +0x6fd0027468f1dcfdull, 0x597186b0153ull, 0x140060ull, 0x16f26555dddull, +0x4fe37c1db1619a73ull, 0x47a0c30bd15ull, 0x11d861ull, 0x5964fb3d7eull, +0x77aa77f86d07c8d9ull, 0x3a39cf03d65ull, 0x20e21cull, 0x37f7fede7cdull, +0xc072e76ad59cf1afull, 0x3a786701dull, 0x34a98c59ull, 0x22b6b1b9aull, +0xfb8e8f1f7781ba75ull, 0xe8ca427d3eull, 0x114a34dull, 0xa344eb94cfull, +0x160e34cf590444abull, 0xe2388f12feull, 0x18f574ull, 0xc303329393ull, +0x2509ddea3a648dd1ull, 0xec762d81bcull, 0x281955ull, 0xc0463d1e65ull, +0xc9ba10cd6eafcf67ull, 0x96a51d06f7ull, 0x156ce72ull, 0x133e2df369ull, +0x1dd4fe261b4adeedull, 0x2736e25406ull, 0xc2bfefull, 0x1354c1f353ull, +0x480258f92fc38de3ull, 0x2599b52bb0ull, 0x1ea450cull, 0x2879f11a3ull, +0x5a3257b1114109c9ull, 0x2978f9f1aaull, 0x22cc30aull, 0x1317311b25ull, +0xf4eeda8f34ab3c1full, 0x1aa70450d9ull, 0x9309d64ull, 0x1187b6925bull, +0x3c2c319ca8612a65ull, 0x73fc01eceull, 0x84d0088ull, 0x3165accf5ull, +0x4f6034e74a16561bull, 0x1f29d53707ull, 0x28c0daaull, 0xd88e07075ull, +0x206665a7072f1cc1ull, 0xda87e7ceaull, 0x25f48c1ull, 0xd3ddb2057ull, +0x100c559d7db417d7ull, 0xb907ebbc2ull, 0x1634188ull, 0xa2eae16c7ull, +0x64c5f83691b47cddull, 0x5aced6ebbull, 0x11c17fb7ull, 0x344109030ull, +0x32a812777eaf7d53ull, 0x1cb63fe4full, 0x1c3a9675ull, 0xb113f938ull, +0x67478d96865ca6b9ull, 0x142fa03aull, 0x51dcb463dull, 0x11359ce7ull, +0x71024e740deb428full, 0x142d3885ull, 0x599d9edd5ull, 0x13b1ae6ull, +0x52c78160b090b655ull, 0xd02101c6ull, 0x65d1b205ull, 0x1c0a0177ull, +0x16917d5f9fde38bull, 0xfb1566c7ull, 0x17029e0ull, 0x1bbe166bull, +0xa6ee688a0d1387b1ull, 0x22c4d384ull, 0x4cd19afcfull, 0x77143f5ull, +0x74babc1be2ed9c47ull, 0x22eda9a6ull, 0x3578b1967ull, 0x189b247dull, +0x7c5cbf2dfc1db6cdull, 0x5f09c060ull, 0x14efd44d4ull, 0x5210e74dull, +0x7c046071c1ac68c3ull, 0x3696c8e6ull, 0x24596d86bull, 0x26060a1ull, +0x84728ab55d399fa9ull, 0x267d7771ull, 0x370ea7405ull, 0x255d1674ull, +0x99f57100ef5404ffull, 0x10c0df86ull, 0x9308fef0dull, 0x9009131ull, +0x3f4c0514b0df5e45ull, 0xf2c3810ull, 0x42bf84d39ull, 0x3aa12b5ull, +0xd01edb572821ecfbull, 0x2a443aeull, 0x4ec8b88639ull, 0x111c73dull, +0xeecb08561bd0cea1ull, 0xbeca231ull, 0x140692508bull, 0x9b36e06ull, +0x8c856facc6335cb7ull, 0x398eab4ull, 0x271008c7a5ull, 0x922ab3ull, +0x23fb9839e8358cbdull, 0x24deb54ull, 0xf9d714151ull, 0xb9c329ull, +0x2005d5de30015033ull, 0x47c06dbull, 0x7240bccbaull, 0x104d115ull, +0x67d59c29e076f499ull, 0x179f009ull, 0x465554ac22ull, 0x10b0767ull, +0x32d2dd34369c836full, 0x13d3fbfull, 0x2902f2fb54ull, 0x7553c3ull, +0x3960c3c99fdc2235ull, 0x1b808baull, 0x21618743cdull, 0x11e7743ull, +0x343bad5adfa9726bull, 0xeef444ull, 0x37f58c51a6ull, 0x3d8a53ull, +0x7a4aadd7b4e5f191ull, 0x129c9ull, 0x6921bb5a2a53ull, 0x6b66ull, +0x9eb7dae5d71c5927ull, 0x31d7f5ull, 0x32f2ff2c6d5ull, 0x22c4eull, +0x1b285999316afeadull, 0x115477ull, 0x1912cf6611eull, 0x801bbull, +0x917aee3d84b533a3ull, 0x71d26full, 0x1473408589aull, 0x6e74ddull, +0x18e6a86b0473a589ull, 0x50a12ull, 0x4f0fabc67d4ull, 0x210a1ull, +0xf22c9887813bbddfull, 0x5b17aull, 0x2a897505c07bull, 0x1f841ull, +0xef7a551239d60225ull, 0x7fb5aull, 0x1e00b98e188bull, 0x41847ull, +0xffd2ad0e77b73dbull, 0x146f14ull, 0xc8500600a3ull, 0xba1full, +0x76743abdfb91f081ull, 0xd5888ull, 0x8e0303c479cull, 0x245a1ull, +0xc2eeb030bcff9197ull, 0x7a4e8ull, 0x198034e02c37ull, 0x343bfull, +0x63cc9c23f0ed0c9dull, 0x6c1e5ull, 0xec4d5841041ull, 0x38178ull, +0x7ad70f846e8f1313ull, 0x7fdf5ull, 0xf5ecec69bc9ull, 0x756b6ull, +0x60de3d71574eb279ull, 0x6ea3ull, 0xe02421997a61ull, 0x18b6ull, +0xd27054901c68b44full, 0x2dd0full, 0x497d639c8f46ull, 0xe135ull, +0xbcf297b8f0dbfe15ull, 0xcf17ull, 0xe992af0ca1abull, 0x32b8ull, +0x96c3ae70323ef14bull, 0xbbdcull, 0xcd7329b68d81ull, 0x1b6full, +0xdc1a13cfa4d3cb71ull, 0xdb16ull, 0x1012fe5ed296full, 0x46e7ull, +0xa1d40a2986f40607ull, 0x8067ull, 0x142a473fdb7beull, 0x1895ull, +0x227f92ef6daab68dull, 0x15ecull, 0x192dda5d5ed25ull, 0xf71ull, +0xc0a4a7810015ee83ull, 0x6064ull, 0x1ffa220762fc8ull, 0x4463ull, +0xd38b6eb9f0e71b69ull, 0x1909ull, 0x8732ce2cc77f4ull, 0xfd5ull, +0x2e588bdb751a66bfull, 0x229cull, 0x156d025c70d97ull, 0x10bbull, +0xd90f7e11dcbd1605ull, 0x760ull, 0x1d6e934381ba2eull, 0x2c5ull, +0x60ab67a4e5aeabbull, 0x1bf7ull, 0x374f26f3e3edull, 0x210ull, +0x224f627be76a8261ull, 0x4f4ull, 0x6ed4d3882b567ull, 0x35ull, +0x300d1ab91bd0b677ull, 0xe9cull, 0x34a002fb76e63ull, 0x823ull, +0x2a63d80e0c52fc7dull, 0x32ull, 0xd90970ebc4383full, 0x2full, +0xb0e94bbc1f90c5f3ull, 0x3b3ull, 0x2fd2ef70381c52ull, 0x29dull, +0x2b5dc22562dbe059ull, 0x30aull, 0xe45055015fff5ull, 0x1c7ull, +0x4a7fd1078807d52full, 0x18dull, 0x300a32f60677d4ull, 0x16bull, +0x41a01ee8ab0849f5ull, 0x13cull, 0x352a3971f57e9dull, 0x29ull, +0x95a7287ad5f6602bull, 0x1d0ull, 0x529130d1034a23ull, 0xbbull, +0x723bacc76bd51551ull, 0x16ull, 0x53142091089af83ull, 0xfull, +0x81c49febaa2ca2e7ull, 0xcdull, 0xa20d44956f5bf4ull, 0x83ull, +0x11593d6b3f54de6dull, 0x63ull, 0x2cdc6b1a7f9078ull, 0x5ull, +0x756c82d6f7069963ull, 0x5cull, 0x146bea3ba565525ull, 0x17ull, +0xda882ab2a88c0149ull, 0x1bull, 0x8180194d6d5c728ull, 0x11ull, +0xbb03671751a7ff9full, 0x20ull, 0x5d81b38ba8d3ffcull, 0x1full, +0x6884fa0a8f0c99e5ull, 0x12ull, 0x5ce7fab40d6088cull, 0xdull, +0x5052a2953c528441ull, 0x7ull, 0xb7984f0bf79809bull, 0x4ull, +0x58dd1583185ecb57ull, 0x9ull, 0x9dfad0e90ee1697ull, 0x8ull, +0xaa6870c376df5c5dull, 0x3ull, 0x38cd7aebd24a741full, 0x0ull, +0x4b21d01617167e39ull, 0x2ull, 0x2590e80b0b8b3f1cull, 0x1ull, +}; + +int main(void) +{ + uint64_t x, y, div, mod; + int i; + + for (i = 0; i < sizeof t/sizeof *t; i++) { + x = t[i].x; + y = t[i].y; + div = x / y; + mod = x % y; + if (div != t[i].div) + t_error("udiv %llu/%llu want %llu got %llu\n", x, y, t[i].div, div); + if (mod != t[i].mod) + t_error("umod %llu%%%llu want %llu got %llu\n", x, y, t[i].mod, mod); + } + + printf("%s finished\n", __FILE__); + return t_status; +} diff --git a/programs/develop/ktcc/trunk/libctest/ungetc.c b/programs/develop/ktcc/trunk/libctest/ungetc.c new file mode 100644 index 0000000000..901efb6b35 --- /dev/null +++ b/programs/develop/ktcc/trunk/libctest/ungetc.c @@ -0,0 +1,55 @@ +#include +#include +#include +//#include +//#include +//#include +#include "test.h" + +#define TEST(r, f, x, m) ( \ + errno = 0, ((r) = (f)) == (x) || \ + (t_error("%s failed (" m ")\n", #f, r, x, strerror(errno)), 0) ) + +#define TEST_S(s, x, m) ( \ + !strcmp((s),(x)) || \ + (t_error("[%s] != [%s] (%s)\n", s, x, m), 0) ) + +int main(void) +{ + int i; + char a[100]; + FILE *f; + + TEST(i, !(f = fopen("_tmpfile.tmp","w+")), 0, "failed to create temp file %d!=%d (%s)"); + + if (!f) return t_status; + + TEST(i, fprintf(f, "hello, world\n"), 13, "%d != %d (%m)"); + TEST(i, fseek(f, 0, SEEK_SET), 0, "%d != %d (%m)"); + + TEST(i, feof(f), 0, "%d != %d"); + TEST(i, fgetc(f), 'h', "'%c' != '%c'"); + TEST(i, ftell(f), 1, "%d != %d"); + TEST(i, ungetc('x', f), 'x', "%d != %d"); + TEST(i, ftell(f), 0, "%d != %d"); + TEST(i, fscanf(f, "%[h]", a), 0, "got %d fields, expected %d"); + TEST(i, ftell(f), 0, "%d != %d"); + TEST(i, fgetc(f), 'x', "'%c' != '%c'"); + TEST(i, ftell(f), 1, "%d != %d"); + + TEST(i, fseek(f, 0, SEEK_SET), 0, "%d != %d"); + TEST(i, ungetc('x', f), 'x', "%d != %d"); + TEST(i, fread(a, 1, sizeof a, f), 14, "read %d, expected %d"); + a[14] = 0; + TEST_S(a, "xhello, world\n", "mismatch reading ungot character"); + + TEST(i, fseek(f, 0, SEEK_SET), 0, "%d != %d"); + TEST(i, fscanf(f, "%[x]", a), 0, "got %d fields, expected %d"); + TEST(i, ungetc('x', f), 'x', "unget failed after fscanf: %d != %d"); + TEST(i, fgetc(f), 'x', "'%c' != '%c'"); + TEST(i, fgetc(f), 'h', "'%c' != '%c'"); + + printf("%s finished\n", __FILE__); + fclose(f); + return t_status; +} diff --git a/programs/develop/ktcc/trunk/readme.txt b/programs/develop/ktcc/trunk/readme.txt index 06c158982f..ef31932c12 100644 --- a/programs/develop/ktcc/trunk/readme.txt +++ b/programs/develop/ktcc/trunk/readme.txt @@ -1,4 +1,4 @@ see source/readme.* source/changelog -source/tcc-doc.info or .texi \ No newline at end of file +source/tcc-doc.info or .texi diff --git a/programs/develop/ktcc/trunk/source/readme_kos32.txt b/programs/develop/ktcc/trunk/source/readme_kos32.txt index 03e633c10e..cc14e7dde4 100644 --- a/programs/develop/ktcc/trunk/source/readme_kos32.txt +++ b/programs/develop/ktcc/trunk/source/readme_kos32.txt @@ -57,33 +57,61 @@ libc: -no "finished" in title of console program after exit console - use con_exit() -bench timing error (0s or 1s) -minimal memory allocator --memmove cannot overlap -libc not full +libc not complete. overall status: no files: assert.h -errno.h +errno.h - in stdio limits.h locale.h setjmp.h signall.h time.h -check functions: +wchar.h +wctype.h + + + +functions absent list: + +math.h +frexp +ldexp +modf +fmod + +HUGE_VAL +NAN + stdio.h: +FOPEN_MAX +L_tmpnam +TMP_MAX Operations on files: none http://www.cplusplus.com/reference/cstdio/ -reopen -setbuf, setvbuf -scanf, sscanf, vfscanf(C11), vscanf(C11), vsscanf(C11) -vfprintf, vsfprintf +freopen +setbuf +setvbuf + + +stdlib.h: +atof +atol +strtol, strtoul +atexit +getenv +system +bsearch +qsort +mblen +mbtowc +wctomb +mbstowcs +wcstombs + +string.h +strxfrm -+fgets, gets -fputs, puts -getchar -putc -+putchar -Error-handling: only feof -Macros: only EOF, NULL, FILE -all files in libc/kolibrisys catalog are stdcall in header, but in asm cdecl