diff --git a/programs/develop/ktcc/trunk/bin/lib/libc.obj.a b/programs/develop/ktcc/trunk/bin/lib/libc.obj.a index 2cbc133460..e1e9c1e85a 100644 Binary files a/programs/develop/ktcc/trunk/bin/lib/libc.obj.a and b/programs/develop/ktcc/trunk/bin/lib/libc.obj.a differ diff --git a/programs/develop/ktcc/trunk/libc.obj/include/assert.h b/programs/develop/ktcc/trunk/libc.obj/include/assert.h new file mode 100644 index 0000000000..4dd392ab0a --- /dev/null +++ b/programs/develop/ktcc/trunk/libc.obj/include/assert.h @@ -0,0 +1,9 @@ +#ifndef _ASSERT_H_ +#define _ASSERT_H_ + +#include +#include + +#define assert(x) ((void)((x) || (__assert_fail(#x, __FILE__, __LINE__, __func__),0))) + +#endif // _ASSERT_H_ \ No newline at end of file diff --git a/programs/develop/ktcc/trunk/libc.obj/include/stdlib.h b/programs/develop/ktcc/trunk/libc.obj/include/stdlib.h index c01384e208..2f2681eed4 100644 --- a/programs/develop/ktcc/trunk/libc.obj/include/stdlib.h +++ b/programs/develop/ktcc/trunk/libc.obj/include/stdlib.h @@ -40,4 +40,7 @@ extern void _FUNC(exit)(int status); extern void _FUNC(srand)(unsigned s); extern int _FUNC(rand)(void); +extern void _FUNC(__assert_fail)(const char *expr, const char *file, int line, const char *func); +extern void _FUNC(qsort)(void *base0, size_t n, size_t size, int (*compar)(const void *, const void *)); + #endif diff --git a/programs/develop/ktcc/trunk/libc.obj/lib/libc.obj.a b/programs/develop/ktcc/trunk/libc.obj/lib/libc.obj.a deleted file mode 100644 index 2cbc133460..0000000000 Binary files a/programs/develop/ktcc/trunk/libc.obj/lib/libc.obj.a and /dev/null differ diff --git a/programs/develop/ktcc/trunk/libc.obj/lib/libtcc.a b/programs/develop/ktcc/trunk/libc.obj/lib/libtcc.a deleted file mode 100644 index 77e05da5e8..0000000000 Binary files a/programs/develop/ktcc/trunk/libc.obj/lib/libtcc.a and /dev/null differ diff --git a/programs/develop/ktcc/trunk/libc.obj/samples/Makefile b/programs/develop/ktcc/trunk/libc.obj/samples/Makefile index 69d6768d74..5b65aa5ab8 100644 --- a/programs/develop/ktcc/trunk/libc.obj/samples/Makefile +++ b/programs/develop/ktcc/trunk/libc.obj/samples/Makefile @@ -14,12 +14,13 @@ whois.kex \ file_io.kex \ tmpdisk_work.kex \ consoleio.kex \ +assert_test.kex \ fasm/sprintf_test.kex \ clayer/rasterworks.kex \ clayer/libimg.kex \ clayer/dialog.kex \ clayer/msgbox.kex \ -clayer/boxlib.kex +clayer/boxlib.kex \ LIBS= -ltcc -ldialog -lrasterworks -limg -lbox -lmsgbox -lnetwork -lc.obj diff --git a/programs/develop/ktcc/trunk/libc.obj/samples/assert_test.c b/programs/develop/ktcc/trunk/libc.obj/samples/assert_test.c new file mode 100644 index 0000000000..0e5711603f --- /dev/null +++ b/programs/develop/ktcc/trunk/libc.obj/samples/assert_test.c @@ -0,0 +1,9 @@ +#include +#include +int a=431; +int b=532; + +int main(){ + assert(a!=b); + assert(a==b); +} \ No newline at end of file diff --git a/programs/develop/ktcc/trunk/libc.obj/source/Makefile b/programs/develop/ktcc/trunk/libc.obj/source/Makefile index 02da7ffcdd..cca348a88f 100644 --- a/programs/develop/ktcc/trunk/libc.obj/source/Makefile +++ b/programs/develop/ktcc/trunk/libc.obj/source/Makefile @@ -22,7 +22,7 @@ all: $(MAKE) -C libtcc rm -rf exports install: - cp -f ../lib/libc.obj ~/.kex/root/RD/1/LIB + cp -f libc.obj ~/.kex/root/RD/1/LIB clean: rm ../../bin/lib/libc.obj.a ../../bin/lib/libtcc.a diff --git a/programs/develop/ktcc/trunk/libc.obj/source/libc.c b/programs/develop/ktcc/trunk/libc.obj/source/libc.c index 1ef9ddf9e7..23ffc9d4c2 100644 --- a/programs/develop/ktcc/trunk/libc.obj/source/libc.c +++ b/programs/develop/ktcc/trunk/libc.obj/source/libc.c @@ -98,6 +98,8 @@ #include "stdlib/itoa.c" #include "stdlib/strtol.c" #include "stdlib/rand.c" +#include "stdlib/qsort.c" +#include "stdlib/assert.c" #include "math/acosh.c" #include "math/asinh.c" diff --git a/programs/develop/ktcc/trunk/libc.obj/source/stdlib/assert.c b/programs/develop/ktcc/trunk/libc.obj/source/stdlib/assert.c new file mode 100644 index 0000000000..553b90465b --- /dev/null +++ b/programs/develop/ktcc/trunk/libc.obj/source/stdlib/assert.c @@ -0,0 +1,14 @@ +#include +#include + + +#pragma GCC push_options +#pragma GCC optimize("O0") + +void __assert_fail(const char *expr, const char *file, int line, const char *func) +{ + fprintf(stdout, "Assertion failed: %s (%s: %s: %d)\n", expr, file, func, line); + exit(0); +} + +#pragma GCC pop_options \ No newline at end of file diff --git a/programs/develop/ktcc/trunk/libc.obj/source/stdlib/qsort.c b/programs/develop/ktcc/trunk/libc.obj/source/stdlib/qsort.c new file mode 100644 index 0000000000..456834ffe7 --- /dev/null +++ b/programs/develop/ktcc/trunk/libc.obj/source/stdlib/qsort.c @@ -0,0 +1,238 @@ +/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ +#include + +/*- + * Copyright (c) 1980, 1983 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that: (1) source distributions retain this entire copyright + * notice and comment, and (2) distributions including binaries display + * the following acknowledgement: ``This product includes software + * developed by the University of California, Berkeley and its contributors'' + * in the documentation or other materials provided with the distribution + * and in all advertising materials mentioning features or use of this + * software. Neither the name of the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* + * qsort.c: + * Our own version of the system qsort routine which is faster by an average + * of 25%, with lows and highs of 10% and 50%. + * The THRESHold below is the insertion sort threshold, and has been adjusted + * for records of size 48 bytes. + * The MTHREShold is where we stop finding a better median. + */ + +#define THRESH 4 /* threshold for insertion */ +#define MTHRESH 6 /* threshold for median */ + +static int (*qcmp)(const void *, const void *); /* the comparison routine */ +static int qsz; /* size of each record */ +static int thresh; /* THRESHold in chars */ +static int mthresh; /* MTHRESHold in chars */ + +/* + * qst: + * Do a quicksort + * First, find the median element, and put that one in the first place as the + * discriminator. (This "median" is just the median of the first, last and + * middle elements). (Using this median instead of the first element is a big + * win). Then, the usual partitioning/swapping, followed by moving the + * discriminator into the right place. Then, figure out the sizes of the two + * partions, do the smaller one recursively and the larger one via a repeat of + * this code. Stopping when there are less than THRESH elements in a partition + * and cleaning up with an insertion sort (in our caller) is a huge win. + * All data swaps are done in-line, which is space-losing but time-saving. + * (And there are only three places where this is done). + */ + +static void +qst(char *base, char *max) +{ + char c, *i, *j, *jj; + int ii; + char *mid, *tmp; + int lo, hi; + + /* + * At the top here, lo is the number of characters of elements in the + * current partition. (Which should be max - base). + * Find the median of the first, last, and middle element and make + * that the middle element. Set j to largest of first and middle. + * If max is larger than that guy, then it's that guy, else compare + * max with loser of first and take larger. Things are set up to + * prefer the middle, then the first in case of ties. + */ + lo = max - base; /* number of elements as chars */ + do { + mid = i = base + qsz * ((lo / qsz) >> 1); + if (lo >= mthresh) + { + j = (qcmp((jj = base), i) > 0 ? jj : i); + if (qcmp(j, (tmp = max - qsz)) > 0) + { + /* switch to first loser */ + j = (j == jj ? i : jj); + if (qcmp(j, tmp) < 0) + j = tmp; + } + if (j != i) + { + ii = qsz; + do { + c = *i; + *i++ = *j; + *j++ = c; + } while (--ii); + } + } + /* + * Semi-standard quicksort partitioning/swapping + */ + for (i = base, j = max - qsz; ; ) + { + while (i < mid && qcmp(i, mid) <= 0) + i += qsz; + while (j > mid) + { + if (qcmp(mid, j) <= 0) + { + j -= qsz; + continue; + } + tmp = i + qsz; /* value of i after swap */ + if (i == mid) + { + /* j <-> mid, new mid is j */ + mid = jj = j; + } + else + { + /* i <-> j */ + jj = j; + j -= qsz; + } + goto swap; + } + if (i == mid) + { + break; + } + else + { + /* i <-> mid, new mid is i */ + jj = mid; + tmp = mid = i; /* value of i after swap */ + j -= qsz; + } + swap: + ii = qsz; + do { + c = *i; + *i++ = *jj; + *jj++ = c; + } while (--ii); + i = tmp; + } + /* + * Look at sizes of the two partitions, do the smaller + * one first by recursion, then do the larger one by + * making sure lo is its size, base and max are update + * correctly, and branching back. But only repeat + * (recursively or by branching) if the partition is + * of at least size THRESH. + */ + i = (j = mid) + qsz; + if ((lo = j - base) <= (hi = max - i)) + { + if (lo >= thresh) + qst(base, j); + base = i; + lo = hi; + } + else + { + if (hi >= thresh) + qst(i, max); + max = j; + } + } while (lo >= thresh); +} + +/* + * qsort: + * First, set up some global parameters for qst to share. Then, quicksort + * with qst(), and then a cleanup insertion sort ourselves. Sound simple? + * It's not... + */ + +void +qsort(void *base0, size_t n, size_t size, int (*compar)(const void *, const void *)) +{ + char *base = (char *)base0; + char c, *i, *j, *lo, *hi; + char *min, *max; + + if (n <= 1) + return; + qsz = size; + qcmp = compar; + thresh = qsz * THRESH; + mthresh = qsz * MTHRESH; + max = base + n * qsz; + if (n >= THRESH) + { + qst(base, max); + hi = base + thresh; + } + else + { + hi = max; + } + /* + * First put smallest element, which must be in the first THRESH, in + * the first position as a sentinel. This is done just by searching + * the first THRESH elements (or the first n if n < THRESH), finding + * the min, and swapping it into the first position. + */ + for (j = lo = base; (lo += qsz) < hi; ) + if (qcmp(j, lo) > 0) + j = lo; + if (j != base) + { + /* swap j into place */ + for (i = base, hi = base + qsz; i < hi; ) + { + c = *j; + *j++ = *i; + *i++ = c; + } + } + /* + * With our sentinel in place, we now run the following hyper-fast + * insertion sort. For each remaining element, min, from [1] to [n-1], + * set hi to the index of the element AFTER which this one goes. + * Then, do the standard insertion sort shift on a character at a time + * basis for each element in the frob. + */ + for (min = base; (hi = min += qsz) < max; ) + { + while (qcmp(hi -= qsz, min) > 0) + /* void */; + if ((hi += qsz) != min) { + for (lo = min + qsz; --lo >= min; ) + { + c = *lo; + for (i = j = lo; (j -= qsz) >= hi; i = j) + *i = *j; + *i = c; + } + } + } +} diff --git a/programs/develop/ktcc/trunk/libc.obj/source/symbols.txt b/programs/develop/ktcc/trunk/libc.obj/source/symbols.txt index 456a47f61a..9b3505dde7 100644 --- a/programs/develop/ktcc/trunk/libc.obj/source/symbols.txt +++ b/programs/develop/ktcc/trunk/libc.obj/source/symbols.txt @@ -60,6 +60,8 @@ realloc strtol srand rand +qsort +__assert_fail !____STRING____ !memcpy memchr @@ -169,4 +171,4 @@ mktime time localtime asctime -difftime \ No newline at end of file +difftime diff --git a/programs/develop/ktcc/trunk/libc/stdlib/assert.c b/programs/develop/ktcc/trunk/libc/stdlib/assert.c index cd13544f7e..b5d6ca901c 100644 --- a/programs/develop/ktcc/trunk/libc/stdlib/assert.c +++ b/programs/develop/ktcc/trunk/libc/stdlib/assert.c @@ -1,21 +1,7 @@ -#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); -} +#include +#include + +void __assert_fail(const char *expr, const char *file, int line, const char *func){ + fprintf(stderr, "Assertion failed: %s (%s: %s: %d)\n", expr, file, func, line); + abort(); +}