├── .gitignore ├── LICENSE ├── README.md └── src ├── ctype.c ├── ctype.h ├── dirent.c ├── dirent.h ├── stdio.c ├── stdio.h ├── stdlib.c ├── stdlib.h ├── string.c └── string.h /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | 4 | # Libraries 5 | *.lib 6 | *.a 7 | 8 | # Shared objects (inc. Windows DLLs) 9 | *.dll 10 | *.so 11 | *.so.* 12 | *.dylib 13 | 14 | # Executables 15 | *.exe 16 | *.out 17 | *.app 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, heiyeluren 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | Redistributions in binary form must reproduce the above copyright notice, this 11 | list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 18 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 21 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | tmlibc 2 | ====== 3 | 4 | Tima(TM-Tiny&Miny) Standard ANSI C based Library 5 | 6 | 最后更新:2008/11/19 v0.0.1
7 | 下载地址:Download 8 | 9 | -------------------------------------------------------------------------------- /src/ctype.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Tima Standard ANSI C based Library 3 | * 4 | * Copyright (C) 2008 heiyeluren. All rights reserved. 5 | * 6 | * Open-source ANSI C library powered by TieMa(TIMA) Studio. 7 | * 8 | * Use and distribution licensed under the BSD license. See 9 | * the LICENSE file for full text. 10 | * 11 | * To learn more open-source code, http://heiyeluren.googlecode.com 12 | * My blog: http://blog.csdn.net/heiyeshuwu 13 | * 14 | * $Id: ctype.c 2008-11-09 01:06 heiyeluren $ 15 | */ 16 | 17 | 18 | #include "ctype.h" 19 | 20 | 21 | /** 22 | * isalnum - checks for an alphanumeric character 23 | * 24 | * @desc it is equivalent to (isalpha(c) || isdigit(c)) 25 | */ 26 | int isalnum(int c){ 27 | return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= 0x30 && c <= 0x39)); 28 | } 29 | 30 | /** 31 | * isalpha - checks for an alphabetic character 32 | * 33 | * @desc in the standard "C" locale, it is equivalent to (isupper(c) || islower(c)). In some 34 | * locales, there may be additional characters for which isalpha() is true--letters 35 | * which are neither upper case nor lower case. 36 | */ 37 | int isalpha(int c){ 38 | return ( (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ); 39 | } 40 | 41 | /** 42 | * isascii - checks whether c is a 7-bit unsigned char value that fits into the ASCII character set. 43 | * 44 | * @desc ASCII 0-127 45 | */ 46 | int isascii(int c){ 47 | return (c >= 0x00 && c <= 0x7f); 48 | } 49 | 50 | /** 51 | * isblank - checks for a blank character; that is, a space or a tab 52 | */ 53 | int isblank(int c){ 54 | return (c == ' ' || c == '\t'); 55 | } 56 | 57 | /** 58 | * iscntrl - checks for a control character 59 | * 60 | * @desc ASCII 0-30 61 | */ 62 | int iscntrl(int c){ 63 | return (c >= 0x00 && c <= 0x1d); 64 | } 65 | 66 | /** 67 | * isdigit - checks for a digit (0 through 9) 68 | */ 69 | int isdigit(int c){ 70 | return (c >= '0' && c <= '9'); 71 | } 72 | 73 | /** 74 | * isgraph - checks for any printable character except space 75 | * 76 | * @desc ASCII 21-126 77 | */ 78 | int isgraph(int c){ 79 | return (c >= 0x21 && c <= 0x7e); 80 | } 81 | 82 | /** 83 | * islower - checks for a lower-case character ('a' through 'z') 84 | */ 85 | int islower(int c){ 86 | return (c >= 'a' && c <= 'z'); 87 | } 88 | 89 | /** 90 | * isprint - checks for any printable character including space 91 | * 92 | * @desc ASCII 20-126 93 | */ 94 | int isprint(int c){ 95 | return (c >= 0x20 && c <= 0x7e); 96 | } 97 | 98 | /** 99 | * ispunct - checks for any printable character which is not a space or an alphanumeric character 100 | */ 101 | int ispunct(int c){ 102 | return ( (c >= 0x21 && c <= 0x7e) && !((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= 0x30 && c <= 0x39)) ); 103 | } 104 | 105 | /** 106 | * isspace - checks for white-space characters 107 | * 108 | * @desc In the "C" and "POSIX" locales, these are: space, form-feed ('\f'), newline ('\n'), 109 | * carriage return ('\r'), horizontal tab ('\t'), and vertical tab ('\v'). 110 | */ 111 | int isspace(int c){ 112 | return (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\v' || c == '\f'); 113 | } 114 | 115 | /** 116 | * isupper - checks for an uppercase letter 117 | */ 118 | int isupper(int c){ 119 | return (c >= 'A' && c <= 'Z'); 120 | } 121 | 122 | /** 123 | * isxdigit - checks for a hexadecimal digits, that is, one of "0123456789abcdefABCDEF" 124 | */ 125 | int isxdigit(int c){ 126 | return ( (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f') ); 127 | } 128 | 129 | 130 | /** 131 | * toascii - convert a byte to 7-bit ASCII 132 | */ 133 | int toascii(int c){ 134 | return c & 0x7f; 135 | } 136 | 137 | /** 138 | * tolower -- upper case to lower case letter conversion 139 | */ 140 | int tolower(int c){ 141 | return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c; 142 | } 143 | 144 | /** 145 | * toupper - lower case to upper case letter conversion 146 | */ 147 | int toupper(int c){ 148 | return (c >= 'a' && c <= 'z') ? c - ('a' - 'A') : c; 149 | } 150 | 151 | 152 | -------------------------------------------------------------------------------- /src/ctype.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tima Standard ANSI C based Library 3 | * 4 | * Copyright (C) 2008 heiyeluren. All rights reserved. 5 | * 6 | * Open-source ANSI C library powered by TieMa(TIMA) Studio. 7 | * 8 | * Use and distribution licensed under the BSD license. See 9 | * the LICENSE file for full text. 10 | * 11 | * To learn more open-source code, http://heiyeluren.googlecode.com 12 | * My blog: http://blog.csdn.net/heiyeshuwu 13 | * 14 | * $Id: ctype.c 2008-11-09 01:06 heiyeluren $ 15 | */ 16 | 17 | /** 18 | * ctype function define 19 | */ 20 | int isalnum(int c); 21 | int isalpha(int c); 22 | int isascii(int c); 23 | int isblank(int c); 24 | int iscntrl(int c); 25 | int isdigit(int c); 26 | int isgraph(int c); 27 | int islower(int c); 28 | int isprint(int c); 29 | int ispunct(int c); 30 | int isspace(int c); 31 | int isupper(int c); 32 | int isxdigit(int c); 33 | int toascii(int c); 34 | int tolower(int c); 35 | int toupper(int c); 36 | 37 | -------------------------------------------------------------------------------- /src/dirent.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heiyeluren/tmlibc/732f1da4a699a3667b6bdf61392fcfa2b503285e/src/dirent.c -------------------------------------------------------------------------------- /src/dirent.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tima Standard ANSI C based Library 3 | * 4 | * Copyright (C) 2008 heiyeluren. All rights reserved. 5 | * 6 | * Open-source ANSI C library powered by TieMa(TIMA) Studio. 7 | * 8 | * Use and distribution licensed under the BSD license. See 9 | * the LICENSE file for full text. 10 | * 11 | * To learn more open-source code, http://heiyeluren.googlecode.com 12 | * My blog: http://blog.csdn.net/heiyeshuwu 13 | * 14 | * $Id: string.c 2008-11-16 16:01 heiyeluren $ 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include /* flags for read and write */ 21 | #include /* typedefs */ 22 | #include /* structure returned by stat */ 23 | 24 | #ifndef NAME_MAX 25 | # define NAME_MAX 255 /* longest filename component; */ 26 | #endif 27 | 28 | #ifndef DIRSIZ 29 | # define DIRSIZ 255 30 | #endif 31 | 32 | 33 | /* system-dependent */ 34 | typedef struct { /* portable directory entry */ 35 | long ino; /* inode number */ 36 | char name[NAME_MAX+1]; /* name + '\0' terminator */ 37 | } Dirent; 38 | 39 | typedef struct { /* minimal DIR: no buffering, etc. */ 40 | int fd; /* file descriptor for the directory */ 41 | Dirent d; /* the directory entry */ 42 | } DIR; 43 | 44 | struct direct { /* directory entry */ 45 | ino_t d_ino; /* inode number */ 46 | char d_name[DIRSIZ]; /* long name does not have '\0' */ 47 | }; 48 | 49 | 50 | 51 | /* function define */ 52 | #define dirfd(dir) ((dir)->fd) 53 | #define rewinddir(dir) (lseek((dir)->fd, 0, SEEK_SET)) 54 | #define seekdir(dir, offset) (lseek((dir)->fd, offset, SEEK_SET)) 55 | 56 | DIR *opendir(const char *name); 57 | DIR *fdopendir(int fd); 58 | int closedir(DIR *dir); 59 | struct dirent *readdir(DIR *dir); 60 | int scandir(const char *dir, struct dirent ***namelist, int(*filter)(const struct dirent *), int(*compar)(const struct dirent **, const struct dirent **)); 61 | 62 | 63 | -------------------------------------------------------------------------------- /src/stdio.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Tima Standard ANSI C based Library 3 | * 4 | * Copyright (C) 2008 heiyeluren. All rights reserved. 5 | * 6 | * Open-source ANSI C library powered by TieMa(TIMA) Studio. 7 | * 8 | * Use and distribution licensed under the BSD license. See 9 | * the LICENSE file for full text. 10 | * 11 | * To learn more open-source code, http://heiyeluren.googlecode.com 12 | * My blog: http://blog.csdn.net/heiyeshuwu 13 | * 14 | * $Id: string.c 2008-11-19 03:04 heiyeluren $ 15 | */ 16 | 17 | #include "stdio.h" 18 | 19 | /** 20 | * _fillbuf - allocate and fill input buffer 21 | * 22 | */ 23 | int _fillbuf(FILE *fp){ 24 | int bufsize; 25 | if ((fp->flag&(_READ|_EOF_ERR)) != _READ) 26 | return EOF; 27 | bufsize = (fp->flag & _UNBUF) ? 1 : BUFSIZ; 28 | if (fp->base == NULL) /* no buffer yet */ 29 | if ((fp->base = (char *) malloc(bufsize)) == NULL) 30 | return EOF; /* can't get buffer */ 31 | fp->ptr = fp->base; 32 | fp->cnt = read(fp->fd, fp->ptr, bufsize); 33 | fp->pos += fp->cnt; 34 | if (--fp->cnt < 0) { 35 | if (fp->cnt == -1) 36 | fp->flag |= _EOF; 37 | else 38 | fp->flag |= _ERR; 39 | fp->cnt = 0; 40 | return EOF; 41 | } 42 | return (unsigned char) *fp->ptr++; 43 | } 44 | 45 | int _flushbuf(int x, FILE *fp) { 46 | unsigned nc; /* of chars to flush */ 47 | int bufsize; /* size of buffer alloc */ 48 | 49 | if (fp < _iob || fp >= _iob + OPEN_MAX) { 50 | return EOF; 51 | } 52 | bufsize = (fp->flag & _UNBUF) ? 1 : BUFSIZ; 53 | if (fp->base == NULL) { 54 | if ((fp->base = (char *)malloc(bufzie) == NULL) { 55 | fp->flag |= _ERR; 56 | return EOF; 57 | } else { 58 | nc = fp->ptr - fp->base; 59 | if (write(fp->fd, fp->base, nc) != nc) { 60 | fp->flag |= _ERR; 61 | return EOF; 62 | } 63 | fp->pos += nc; 64 | } 65 | fp->ptr = fp->base; 66 | *fp->ptr++ = (char)x; 67 | fp->cnt = bufsize - 1; 68 | return x; 69 | } 70 | 71 | } 72 | 73 | 74 | /** 75 | * fflush - flush a stream 76 | */ 77 | int fflush() { 78 | int rc = 0; 79 | 80 | if (fp < _iob || fp >= _iob + OPEN_MAX) { 81 | return EOF; 82 | } 83 | if (fp->flag & _WRITE) { 84 | rc = _flushbuf(0, fp); 85 | } 86 | fp->ptr = fp->base; 87 | fp->cnt = (fp->flag & _UNBUF) ? 1 : BUFSIZ; 88 | return rc; 89 | } 90 | 91 | /** 92 | * fpurge - purge a stream 93 | */ 94 | int fpurge(FILE *stream) { 95 | if (stream == NULL) { 96 | return EOF; 97 | } 98 | if (!stream->flag) { 99 | errno = EBADF; 100 | return EOF; 101 | } 102 | if (fp->base){ 103 | free(fp->base); 104 | } 105 | fp->fd = -1; 106 | fp->cnt = 0; 107 | fp->base = NULL; 108 | fp->flag = 0; 109 | fp->pos = 0; 110 | 111 | return 0; 112 | } 113 | 114 | 115 | /** 116 | * fseek, ftell, rewind - reposition a stream 117 | */ 118 | int fseek(FILE *stream, long offset, int whence) { 119 | unsigned nc; 120 | long rc = 0; 121 | 122 | if (fp->flag & _READ) { 123 | if (whence == SEEK_CUR) { 124 | offset -= fp->cnt; 125 | } 126 | rc = lseek(fp->fd, offset, whence); 127 | fp->cnt = 0; 128 | } else if (fp->fag & _WRITE) { 129 | if ((nc = fp->ptr - fp->base) > 0) { 130 | if (write(fp->fd, fp->base, nc) != nc) { 131 | rc = -1; 132 | } 133 | } 134 | if (rc != -1) { 135 | rc = lseek(fp->fd, offset, whence); 136 | } 137 | } 138 | stream->pos = rc; 139 | 140 | return (rc == -1) ? -1 : 0; 141 | } 142 | 143 | /** 144 | * fopen, fdopen, freopen - stream open functions 145 | */ 146 | FILE *fopen(const char *path, const char *mode) { 147 | int fd; 148 | FILE *fp; 149 | if (*mode != 'r' && *mode != 'w' && *mode != 'a') 150 | return NULL; 151 | for (fp = _iob; fp < _iob + OPEN_MAX; fp++) 152 | if ((fp->flag & (_READ | _WRITE)) == 0) 153 | break; /* found free slot */ 154 | if (fp >= _iob + OPEN_MAX) /* no free slots */ 155 | return NULL; 156 | if (*mode == 'w') { 157 | fd = creat(name, PERMS); 158 | } else if (*mode == 'a') { 159 | if ((fd = open(name, O_WRONLY, 0)) == -1) 160 | fd = creat(name, PERMS); 161 | lseek(fd, 0L, 2); 162 | } else { 163 | fd = open(name, O_RDONLY, 0); 164 | } 165 | if (fd == -1) /* couldn't access name */ 166 | return NULL; 167 | fp->fd = fd; 168 | fp->cnt = 0; 169 | fp->base = NULL; 170 | fp->flag = (*mode == 'r') ? _READ : _WRITE; 171 | fp->pos = 0; 172 | 173 | return fp; 174 | } 175 | 176 | /** 177 | * fopen, fdopen, freopen - stream open functions 178 | */ 179 | FILE *fdopen(int fildes, const char *mode) { 180 | FILE *fp; 181 | 182 | if (*mode != 'r' && *mode != 'w' && *mode != 'a') 183 | return NULL; 184 | for (fp = _iob; fp < _iob + OPEN_MAX; fp++) 185 | if ((fp->flag & (_READ | _WRITE)) == 0) 186 | break; /* found free slot */ 187 | if (fp >= _iob + OPEN_MAX) /* no free slots */ 188 | return NULL; 189 | if (fildes == -1) /* couldn't access name */ 190 | return NULL; 191 | fp->fd = fildes; 192 | fp->cnt = 0; 193 | fp->base = NULL; 194 | fp->flag = (*mode == 'r') ? _READ : _WRITE; 195 | fp->pos = 0; 196 | 197 | return fp; 198 | } 199 | 200 | /** 201 | * fopen, fdopen, freopen - stream open functions 202 | */ 203 | FILE *freopen(const char *path, const char *mode, FILE *stream) { 204 | int fd; 205 | FILE *fp = stream; 206 | if (fp != NULL){ 207 | fclose(fp); 208 | } 209 | if (*mode != 'r' && *mode != 'w' && *mode != 'a') 210 | return NULL; 211 | for (fp = _iob; fp < _iob + OPEN_MAX; fp++) 212 | if ((fp->flag & (_READ | _WRITE)) == 0) 213 | break; /* found free slot */ 214 | if (fp >= _iob + OPEN_MAX) /* no free slots */ 215 | return NULL; 216 | if (*mode == 'w') { 217 | fd = creat(name, PERMS); 218 | } else if (*mode == 'a') { 219 | if ((fd = open(name, O_WRONLY, 0)) == -1) 220 | fd = creat(name, PERMS); 221 | lseek(fd, 0L, 2); 222 | } else { 223 | fd = open(name, O_RDONLY, 0); 224 | } 225 | if (fd == -1) /* couldn't access name */ 226 | return NULL; 227 | fp->fd = fd; 228 | fp->cnt = 0; 229 | fp->base = NULL; 230 | fp->flag = (*mode == 'r') ? _READ : _WRITE; 231 | fp->pos = 0; 232 | 233 | return fp; 234 | } 235 | 236 | 237 | /** 238 | * fclose - close a stream 239 | */ 240 | int fclose(FILE *fp) { 241 | int rc; 242 | 243 | if ((rc = fflush(fp)) != EOF) { 244 | free(fp->base); 245 | fp->ptr = NULL; 246 | fp->cnt = 0; 247 | fp->base = NULL; 248 | fp->flag &= ~(_READ | _WRITE); 249 | fp->pos = 0; 250 | //close(fp->fd); 251 | } 252 | return rc; 253 | } 254 | 255 | /** 256 | * fgetc, fgets, getc, getchar, gets, ungetc - input of characters and strings 257 | */ 258 | int ungetc(int c, FILE *stream) { 259 | int n = stream->cnt, m = stream->cnt; 260 | 261 | if (stream == NULL) { 262 | return EOF; 263 | } 264 | 265 | for (; n--; stream->ptr[n+1] = stream->ptr[n]); 266 | stream->ptr = c; 267 | 268 | return c; 269 | } 270 | 271 | /** 272 | * fgetc, fgets, getc, getchar, gets, ungetc - input of characters and strings 273 | */ 274 | int fgetc(FILE *stream) { 275 | unsigned char ret; 276 | 277 | ret = --stream->cnt >= 0 ? (unsigned char)stream->ptr++ : _fillbuf(stream); 278 | if (ret == NULL) { 279 | return EOF; 280 | } 281 | return ret 282 | } 283 | 284 | /** 285 | * fgetc, fgets, getc, getchar, gets, ungetc - input of characters and strings 286 | */ 287 | char *fgets(char *s, int size, FILE *stream) { 288 | char *buf = s; 289 | 290 | if (buf == NULL || size <= 0) { 291 | return NULL; 292 | } 293 | while (size--) { 294 | *buf++ = fgetc(stream); 295 | if (*buf == EOF || *buf == '\n') 296 | break; 297 | } 298 | if (buf != NULL){ 299 | *buf = '\0'; 300 | return s; 301 | } 302 | return NULL; 303 | } 304 | 305 | /** 306 | * fgetc, fgets, getc, getchar, gets, ungetc - input of characters and strings 307 | */ 308 | char *gets(char *s) { 309 | char *buf = s; 310 | 311 | if (buf == NULL) { 312 | return NULL; 313 | } 314 | for (;;) { 315 | *buf++ = fgetc(stdin); 316 | if (*buf == EOF || *buf == '\n') 317 | break; 318 | } 319 | if (buf != NULL){ 320 | *buf = '\0'; 321 | return s; 322 | } 323 | return NULL; 324 | } 325 | 326 | /** 327 | * fputc, fputs, putc, putchar, puts - output of characters and strings 328 | */ 329 | int fputc(int c, FILE * stream) { 330 | unsigned char ret; 331 | 332 | ret = --stream->cnt >= 0 ? stream->ptr++ = c : _fillbuf(stream); 333 | if (ret == NULL || ret == EOF) { 334 | return EOF; 335 | } 336 | return c; 337 | } 338 | 339 | /** 340 | * fputc, fputs, putc, putchar, puts - output of characters and strings 341 | */ 342 | int fputs(const char *s, FILE * stream) { 343 | char c; 344 | int n = 0; 345 | 346 | while ((c = *s++)) { 347 | if (fputc(c, stream) == EOF){ 348 | return EOF; 349 | } 350 | n++; 351 | } 352 | return n; 353 | } 354 | 355 | /** 356 | * fputc, fputs, putc, putchar, puts - output of characters and strings 357 | */ 358 | int puts(const char *s) { 359 | char *buf = s, c; 360 | int n = 0; 361 | 362 | if (buf == NULL) { 363 | return EOF; 364 | } 365 | while ((c = *s++)) } 366 | if (fputc(c, stdin) == EOF) { 367 | return EOF; 368 | } 369 | n++; 370 | } 371 | return n; 372 | } 373 | 374 | /** 375 | * fread, fwrite - binary stream input/output 376 | */ 377 | size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) { 378 | char *buf = (char *)ptr; 379 | int n = size * nmemb, total = 0; 380 | int c; 381 | 382 | if (ptr == NULL || feof (stream) || ferror (stream)) 383 | return 0; 384 | 385 | while (n--) { 386 | if ((c = fgetc(stream)) == EOF){ 387 | break; 388 | } 389 | total++; 390 | *buf++ = (char)c; 391 | } 392 | return (int)(total / size); 393 | } 394 | 395 | /** 396 | * fread, fwrite - binary stream input/output 397 | */ 398 | size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream) { 399 | char *buf = (char *)ptr; 400 | int n = size * nmemb, total = 0; 401 | int c; 402 | 403 | if (ptr == NULL || feof (stream) || ferror (stream)) 404 | return 0; 405 | 406 | while (n-- && (c = *buf++)) { 407 | if (fputc(c, stream) == EOF){ 408 | break; 409 | } 410 | total++; 411 | } 412 | return (int)(total / size); 413 | } 414 | 415 | 416 | -------------------------------------------------------------------------------- /src/stdio.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tima Standard ANSI C based Library 3 | * 4 | * Copyright (C) 2008 heiyeluren. All rights reserved. 5 | * 6 | * Open-source ANSI C library powered by TieMa(TIMA) Studio. 7 | * 8 | * Use and distribution licensed under the BSD license. See 9 | * the LICENSE file for full text. 10 | * 11 | * To learn more open-source code, http://heiyeluren.googlecode.com 12 | * My blog: http://blog.csdn.net/heiyeshuwu 13 | * 14 | * $Id: string.c 2008-11-19 03:04 heiyeluren $ 15 | */ 16 | 17 | #include 18 | //#include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #ifndef STDIN_FILENO 25 | #define STDIN_FILENO 0 26 | #endif 27 | #ifndef STDOUT_FILENO 28 | #define STDOUT_FILENO 1 29 | #endif 30 | #ifndef STDERR_FILENO 31 | #define STDERR_FILENO 2 32 | #endif 33 | 34 | #ifndef _STDIO_H 35 | # define _STDIO_H 1 36 | #endif 37 | 38 | #define __UNGET_SIZE 10 39 | 40 | #define NULL 0 41 | #define EOF (-1) 42 | #define BUFSIZ 1024 43 | #define OPEN_MAX 37 /* max #files open at once */ 44 | #define PERMS 0666/* RW for owner, group, others */ 45 | 46 | /* file position operate const */ 47 | #define SEEK_SET 0 /* Seek from beginning of file. */ 48 | #define SEEK_CUR 1 /* Seek from current position. */ 49 | #define SEEK_END 2 /* Seek from end of file. */ 50 | 51 | /* standard io buffer flag */ 52 | #define _IOFBF 0 /* fully buffered */ 53 | #define _IOLBF 1 /* line buffered */ 54 | #define _IONBF 2 /* unbuffered */ 55 | 56 | /* file operate mode & flag */ 57 | enum _flags { 58 | _READ = 01, /* file open for reading */ 59 | _WRITE = 02, /* file open for writing */ 60 | _UNBUF = 04, /* file is unbuffered */ 61 | _EOF = 010, /* EOF has occurred on this file */ 62 | _ERR = 020 /* error occurred on this file */ 63 | }; 64 | 65 | /* file stream struct pointer */ 66 | typedef struct _iobuf { 67 | int cnt; /* characters left */ 68 | char *ptr; /* next character position */ 69 | char *base; /* location of buffer */ 70 | int flag; /* mode of file access */ 71 | int fd; /* file descriptor */ 72 | long pos; /* pointer current position */ 73 | //int err; /* error flag */ 74 | } FILE; 75 | 76 | /* default: standard input, standard output, stander error */ 77 | FILE _iob[OPEN_MAX] = { /* stdin, stdout, stderr */ 78 | { 0, (char *) 0, (char *) 0, _READ, STDIN_FILENO, 0 }, 79 | { 0, (char *) 0, (char *) 0, _WRITE, STDOUT_FILENO, 0 }, 80 | { 0, (char *) 0, (char *) 0, _WRITE, | _UNBUF, STDERR_FILENO, 0 } 81 | }; 82 | //extern FILE _iob[OPEN_MAX]; 83 | #define stdin (&_iob[0]) 84 | #define stdout (&_iob[1]) 85 | #define stderr (&_iob[2]) 86 | 87 | /* internal function define */ 88 | int _fillbuf(FILE *fp); 89 | int _flushbuf(int x, FILE *fp); 90 | 91 | /* external function define */ 92 | void setbuf(FILE *stream, char *buf); 93 | void setbuffer(FILE *stream, char *buf, size_t size); 94 | void setlinebuf(FILE *stream); 95 | int setvbuf(FILE *stream, char *buf, int mode , size_t size); 96 | int fflush(FILE *stream); 97 | int fpurge(FILE *stream); 98 | void clearerr(FILE * stream); 99 | 100 | int fseek(FILE *stream, long offset, int whence); 101 | long ftell(FILE *stream); 102 | void rewind(FILE *stream); 103 | 104 | FILE *fopen(const char *path, const char *mode); 105 | FILE *fdopen(int fildes, const char *mode); 106 | FILE *freopen(const char *path, const char *mode, FILE *stream); 107 | int fclose(FILE *fp); 108 | 109 | int ungetc(int c, FILE *stream); 110 | int fgetc(FILE *stream); 111 | char *fgets(char *s, int size, FILE *stream); 112 | char *gets(char *s); 113 | int fputc(int c, FILE * stream); 114 | int fputs(const char * s, FILE * stream); 115 | int puts(const char *s); 116 | 117 | 118 | size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); 119 | size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream); 120 | 121 | 122 | /* inline function */ 123 | #define feof(p) ((p)->flag & _EOF) != 0) 124 | #define ferror(p) ((p)->flag & _ERR) != 0) 125 | #define fileno(p) ((p)->fd) 126 | #define getc(p) (--(p)->cnt >= 0 ? (unsigned char) *(p)->ptr++ : _fillbuf(p)) 127 | #define putc(x,p) (--(p)->cnt >= 0 ? *(p)->ptr++ = (x) : _flushbuf((x),p)) 128 | #define getchar() getc(stdin) 129 | #define putchar(x) putc((x), stdout) 130 | #define ftell(p) ((p)->pos) 131 | #define rewind(p) (lseek((p)->fd, 0, SEEK_SET)&&((p)->pos = 0)) 132 | #define clearerr(p) ((p)->flag = (p)->flag^((p)->flag&_ERR)) 133 | 134 | 135 | -------------------------------------------------------------------------------- /src/stdlib.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Tima Standard ANSI C based Library 3 | * 4 | * Copyright (C) 2008 heiyeluren. All rights reserved. 5 | * 6 | * Open-source ANSI C library powered by TieMa(TIMA) Studio. 7 | * 8 | * Use and distribution licensed under the BSD license. See 9 | * the LICENSE file for full text. 10 | * 11 | * To learn more open-source code, http://heiyeluren.googlecode.com 12 | * My blog: http://blog.csdn.net/heiyeshuwu 13 | * 14 | * $Id: stdlib.c 2008-11-09 23:31 heiyeluren $ 15 | */ 16 | 17 | #include "stdlib.h" 18 | 19 | 20 | 21 | /*************************************** 22 | * 23 | * String conversion function 24 | * 25 | ***************************************/ 26 | 27 | 28 | /** 29 | * atof - convert ASCII string to double 30 | * 31 | * @desc The function converts the initial portion of the string pointed to by nptr to double. The behavior is 32 | the same as strtod(nptr, (char **) NULL); 33 | * @return The converted value 34 | */ 35 | double atof(const char *nptr){ 36 | double val, power; 37 | int i, sign; 38 | const char *s = nptr; 39 | 40 | for (i = 0; isspace(s[i]); i++) /* skip white space */ 41 | ; 42 | sign = (s[i] == '-') ? -1 : 1; 43 | if (s[i] == '+' || s[i] == '-') 44 | i++; 45 | for (val = 0.0; isdigit(s[i]); i++) 46 | val = 10.0 * val + (s[i] - '0'); 47 | if (s[i] == '.') 48 | i++; 49 | for (power = 1.0; isdigit(s[i]); i++){ 50 | val = 10.0 * val + (s[i] - '0'); 51 | power *= 10; 52 | } 53 | return sign * val / power; 54 | } 55 | 56 | /** 57 | * atoi - convert ASCII string to integer 58 | * 59 | * @desc The function converts the initial portion of the string pointed to by nptr to int. The behavior is the 60 | * same as strtol(nptr, (char **) NULL, 10); 61 | * @return The converted value 62 | */ 63 | int atoi(const char *nptr){ 64 | int i, n, sign; 65 | const char *s = nptr; 66 | 67 | for (i = 0; isspace(s[i]); i++) ;/* skip white space */ 68 | sign = (s[i] == '-') ? -1 : 1; 69 | if (s[i] == '+' || s[i] == '-') /* skip sign */ 70 | i++; 71 | for (n = 0; isdigit(s[i]); i++) 72 | n = 10 * n + (s[i] - '0'); 73 | return sign * n; 74 | } 75 | 76 | /** 77 | * atol - convert ASCII string to long integer 78 | * 79 | * @desc The function converts the initial portion of the string pointed to by nptr to int. The behavior is the 80 | * same as strtol(nptr, (char **) NULL, 10); 81 | * @return The converted value 82 | */ 83 | long atol(const char *nptr){ 84 | long ret = 0L; 85 | int neg = 0; 86 | const char *s = nptr; 87 | 88 | while (s && *s && isspace(*s)) 89 | s++; 90 | if (*s == '-' || *s == '+'){ 91 | neg = *s == '-'; 92 | s++; 93 | } 94 | for ( ; s && *s && isdigit (*s); s++) 95 | ret = (ret * 10) + (isdigit (*s) ? *s - '0' : *s); 96 | return (neg ? -ret : ret); 97 | } 98 | 99 | 100 | /** 101 | * strtod - convert ASCII string to floating point 102 | * 103 | * @desc The functions convert the initial portion of the string pointed to by nptr to double, float, and long double 104 | * representation, respectively. 105 | * @return These functions return the converted value 106 | */ 107 | double strtod(char *str, char **ptr){ 108 | char *p; 109 | //const char *str = nptr; 110 | //char **ptr = endptr; 111 | 112 | if (ptr == (char **)0) 113 | return atof (str); 114 | 115 | p = str; 116 | 117 | while (isspace (*p)) 118 | ++p; 119 | 120 | if (*p == '+' || *p == '-') 121 | ++p; 122 | 123 | /* INF or INFINITY. */ 124 | if ((p[0] == 'i' || p[0] == 'I') && (p[1] == 'n' || p[1] == 'N') && (p[2] == 'f' || p[2] == 'F')){ 125 | if ((p[3] == 'i' || p[3] == 'I') && (p[4] == 'n' || p[4] == 'N') && (p[5] == 'i' || p[5] == 'I') && (p[6] == 't' || p[6] == 'T') && (p[7] == 'y' || p[7] == 'Y')){ 126 | *ptr = p + 7; 127 | return atof (str); 128 | } else { 129 | *ptr = p + 3; 130 | return atof (str); 131 | } 132 | } 133 | 134 | /* NAN or NAN(foo). */ 135 | if ((p[0] == 'n' || p[0] == 'N') && (p[1] == 'a' || p[1] == 'A') && (p[2] == 'n' || p[2] == 'N')){ 136 | p += 3; 137 | if (*p == '('){ 138 | ++p; 139 | while (*p != '\0' && *p != ')') 140 | ++p; 141 | if (*p == ')') 142 | ++p; 143 | } 144 | *ptr = p; 145 | return atof (str); 146 | } 147 | 148 | /* digits, with 0 or 1 periods in it. */ 149 | if (isdigit (*p) || *p == '.'){ 150 | int got_dot = 0; 151 | while (isdigit (*p) || (!got_dot && *p == '.')){ 152 | if (*p == '.') 153 | got_dot = 1; 154 | ++p; 155 | } 156 | 157 | /* Exponent. */ 158 | if (*p == 'e' || *p == 'E'){ 159 | int i; 160 | i = 1; 161 | if (p[i] == '+' || p[i] == '-') 162 | ++i; 163 | if (isdigit (p[i])){ 164 | while (isdigit (p[i])) 165 | ++i; 166 | *ptr = p + i; 167 | return atof (str); 168 | } 169 | } 170 | *ptr = p; 171 | return atof (str); 172 | } 173 | /* Didn't find any digits. Doesn't look like a number. */ 174 | *ptr = str; 175 | return 0.0; 176 | } 177 | 178 | 179 | 180 | /** 181 | * strtol - convert a string to a long integer 182 | * 183 | * @desc The function converts the initial part of the string in nptr to a long integer value according to the 184 | * given base, which must be between 2 and 36 inclusive, or be the special value 0. 185 | * @return The function returns the result of the conversion, unless the value would underflow or overflow. If 186 | * an underflow occurs, strtol() returns LONG_MIN. If an overflow occurs, strtol() returns LONG_MAX. In both 187 | * cases, errno is set to ERANGE. Precisely the same holds for strtoll() (with LLONG_MIN and LLONG_MAX instead of 188 | * LONG_MIN and LONG_MAX). 189 | */ 190 | long int strtol(const char *nptr, char **endptr, int base){ 191 | const char *s = nptr; 192 | unsigned long acc; 193 | int c; 194 | unsigned long cutoff; 195 | int neg = 0, any, cutlim; 196 | 197 | /* 198 | * Skip white space and pick up leading +/- sign if any. 199 | * If base is 0, allow 0x for hex and 0 for octal, else 200 | * assume decimal; if base is already 16, allow 0x. 201 | */ 202 | do { 203 | c = *s++; 204 | } while (isspace(c)); 205 | if (c == '-') { 206 | neg = 1; 207 | c = *s++; 208 | } else if (c == '+') 209 | c = *s++; 210 | if ((base == 0 || base == 16) && 211 | c == '0' && (*s == 'x' || *s == 'X')) { 212 | c = s[1]; 213 | s += 2; 214 | base = 16; 215 | } 216 | if (base == 0) 217 | base = c == '0' ? 8 : 10; 218 | 219 | /* 220 | * Compute the cutoff value between legal numbers and illegal 221 | * numbers. That is the largest legal value, divided by the 222 | * base. An input number that is greater than this value, if 223 | * followed by a legal input character, is too big. One that 224 | * is equal to this value may be valid or not; the limit 225 | * between valid and invalid numbers is then based on the last 226 | * digit. For instance, if the range for longs is 227 | * [-2147483648..2147483647] and the input base is 10, 228 | * cutoff will be set to 214748364 and cutlim to either 229 | * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated 230 | * a value > 214748364, or equal but the next digit is > 7 (or 8), 231 | * the number is too big, and we will return a range error. 232 | * 233 | * Set any if any `digits' consumed; make it negative to indicate 234 | * overflow. 235 | */ 236 | cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; 237 | cutlim = cutoff % (unsigned long)base; 238 | cutoff /= (unsigned long)base; 239 | for (acc = 0, any = 0;; c = *s++) { 240 | if (isdigit(c)) 241 | c -= '0'; 242 | else if (isalpha(c)) 243 | c -= isupper(c) ? 'A' - 10 : 'a' - 10; 244 | else 245 | break; 246 | if (c >= base) 247 | break; 248 | if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 249 | any = -1; 250 | else { 251 | any = 1; 252 | acc *= base; 253 | acc += c; 254 | } 255 | } 256 | if (any < 0) { 257 | acc = neg ? LONG_MIN : LONG_MAX; 258 | errno = ERANGE; 259 | } else if (neg) 260 | acc = -acc; 261 | if (endptr != 0) 262 | *endptr = (char *) (any ? s - 1 : nptr); 263 | return (acc); 264 | } 265 | 266 | 267 | /** 268 | * strtoul - convert a string to an unsigned long integer 269 | * 270 | * @desc The function converts the initial part of the string in nptr to an unsigned long integer value 271 | * according to the given base, which must be between 2 and 36 inclusive, or be the special value 0 272 | * @return The function returns either the result of the conversion or, if there was a leading minus sign, the 273 | * negation of the result of the conversion represented as an unsigned value, unless the original (non-negated) 274 | * value would overflow; in the latter case, strtoul() returns ULONG_MAX and sets the global variable errno to 275 | * ERANGE. Precisely the same holds for strtoull() (with ULLONG_MAX instead of ULONG_MAX). 276 | */ 277 | unsigned long int strtoul(const char *nptr, char **endptr, int base){ 278 | const char *s = nptr; 279 | unsigned long acc; 280 | int c; 281 | unsigned long cutoff; 282 | int neg = 0, any, cutlim; 283 | 284 | /* 285 | * See strtol for comments as to the logic used. 286 | */ 287 | do { 288 | c = *s++; 289 | } while (isspace(c)); 290 | if (c == '-') { 291 | neg = 1; 292 | c = *s++; 293 | } else if (c == '+') 294 | c = *s++; 295 | if ((base == 0 || base == 16) && 296 | c == '0' && (*s == 'x' || *s == 'X')) { 297 | c = s[1]; 298 | s += 2; 299 | base = 16; 300 | } 301 | if (base == 0) 302 | base = c == '0' ? 8 : 10; 303 | cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; 304 | cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; 305 | for (acc = 0, any = 0;; c = *s++) { 306 | if (isdigit(c)) 307 | c -= '0'; 308 | else if (isalpha(c)) 309 | c -= isupper(c) ? 'A' - 10 : 'a' - 10; 310 | else 311 | break; 312 | if (c >= base) 313 | break; 314 | if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 315 | any = -1; 316 | else { 317 | any = 1; 318 | acc *= base; 319 | acc += c; 320 | } 321 | } 322 | if (any < 0) { 323 | acc = ULONG_MAX; 324 | errno = ERANGE; 325 | } else if (neg) 326 | acc = -acc; 327 | if (endptr != 0) 328 | *endptr = (char *) (any ? s - 1 : nptr); 329 | 330 | return (acc); 331 | } 332 | 333 | 334 | 335 | /*************************************** 336 | * 337 | * Math function 338 | * 339 | ***************************************/ 340 | 341 | /** 342 | * abs - compute the absolute value of an integer 343 | */ 344 | int abs(int j){ 345 | return j < 0 ? -j : j; 346 | } 347 | 348 | /** 349 | * labs - compute the absolute value of an integer 350 | */ 351 | long int labs(long int j){ 352 | return j < 0 ? -j : j; 353 | } 354 | 355 | /** 356 | * llabs - compute the absolute value of an integer 357 | */ 358 | long long int llabs(long long int j){ 359 | return j < 0 ? -j : j; 360 | } 361 | 362 | 363 | 364 | /*************************************** 365 | * 366 | * Data Structure and Algorithm function 367 | * 368 | ***************************************/ 369 | 370 | /** 371 | * bsearch - binary search of a sorted array 372 | * 373 | * @desc The function searches an array of nmemb objects, the initial member of which is pointed to by base, for a member 374 | * that matches the object pointed to by key. The size of each member of the array is specified by size 375 | * @return The function returns a pointer to a matching member of the array, or NULL if no match is found. If there are 376 | * multiple elements that match the key, the element returned is unspecified. 377 | */ 378 | void *bsearch (const void *key, const void *base, size_t nmemb, size_t size, int (*compar) (const void *, const void *)){ 379 | size_t l, u, idx; 380 | const void *p; 381 | int comparison; 382 | 383 | l = 0; 384 | u = nmemb; 385 | while (l < u){ 386 | idx = (l + u) / 2; 387 | p = (void *) (((const char *) base) + (idx * size)); 388 | comparison = (*compar) (key, p); 389 | if (comparison < 0) 390 | u = idx; 391 | else if (comparison > 0) 392 | l = idx + 1; 393 | else 394 | return (void *) p; 395 | } 396 | 397 | return NULL; 398 | } 399 | 400 | 401 | /** 402 | * swap - swap two variables (for qsort) 403 | */ 404 | static void swap(void *base, size_t i, size_t j, size_t size){ 405 | void *tmp = malloc(size); 406 | 407 | memcpy(tmp, (char *)base + i * size, size); 408 | memmove((char *)base + i * size, (char *)base + j * size, size); 409 | memcpy((char *)base + j * size, tmp, size); 410 | free(tmp); 411 | } 412 | 413 | /** 414 | * qsort - sorts an array 415 | * 416 | * @desc The function sorts an array with nmemb elements of size size. The base argument points to the start of 417 | * the array 418 | * @return The function returns no value 419 | */ 420 | void qsort(void *base, size_t nmemb, size_t size, int (*compar) (const void *, const void *)){ 421 | int i, last; 422 | 423 | if (nmemb <= 1) 424 | return; 425 | 426 | swap(base, 0, nmemb / 2, size); 427 | 428 | last = 0; 429 | for (i = 1; i < nmemb; i++) 430 | if (compar((char *)base + (i * size), base) < 0) 431 | swap(base, i, ++last, size); 432 | 433 | swap(base, 0, last, size); 434 | 435 | qsort(base, last, size, compar); 436 | qsort((char *)base + (last + 1) * size, nmemb - last - 1, size, compar); 437 | } 438 | 439 | 440 | /** 441 | * srand - pseudo-random number generator 442 | * 443 | * @desc The function sets its argument as the seed for a new sequence of pseudo-random integers to be returned 444 | * by rand(). These sequences are repeatable by calling srand() with the same seed value. 445 | * If no seed value is provided, the rand() function is automatically seeded with a value of 1 446 | * @return The function returns no value 447 | */ 448 | void srand(unsigned int seed){ 449 | __rand_next__ = seed; 450 | } 451 | 452 | 453 | /** 454 | * rand - pseudo-random number generator 455 | * 456 | * @desc The function returns a pseudo-random integer between 0 and RAND_MAX. 457 | * @return The functions return a value between 0 and RAND_MAX. 458 | */ 459 | int rand(void){ 460 | __rand_next__ = __rand_next__ * 1103515245 + 12345; 461 | return (unsigned int)(__rand_next__ / 65536) % 32768; 462 | } 463 | 464 | 465 | /** 466 | * rand - pseudo-random number generator 467 | * 468 | * @desc The function is supplied with a pointer to an unsigned int, to be used as state. This is a very small amount of 469 | * state, so this function will be a weak pseudo-random generator. 470 | * @return The functions return a value between 0 and RAND_MAX. 471 | */ 472 | int rand_r(unsigned int *seed){ 473 | unsigned int next = *seed; 474 | int result; 475 | 476 | next *= 1103515245; 477 | next += 12345; 478 | result = (unsigned int) (next / 65536) % 2048; 479 | 480 | next *= 1103515245; 481 | next += 12345; 482 | result <<= 10; 483 | result ^= (unsigned int) (next / 65536) % 1024; 484 | 485 | next *= 1103515245; 486 | next += 12345; 487 | result <<= 10; 488 | result ^= (unsigned int) (next / 65536) % 1024; 489 | 490 | *seed = next; 491 | 492 | return result; 493 | } 494 | 495 | 496 | 497 | /*************************************** 498 | * 499 | * Memory control function 500 | * 501 | ***************************************/ 502 | 503 | /** 504 | * morecore - ask system for more memory (for malloc) 505 | * 506 | * @desc system implement (like UNIX os use sbrk() alloc data segment) 507 | */ 508 | static Header *morecore(size_t nu){ 509 | char *cp, *sbrk(int); 510 | Header *up; 511 | if (nu < NALLOC) 512 | nu = NALLOC; 513 | cp = sbrk(nu * sizeof(Header)); 514 | if (cp == (char *) -1) /* no space at all */ 515 | return NULL; 516 | up = (Header *) cp; 517 | up->s.size = nu; 518 | free((void *)(up+1)); 519 | return freep; 520 | } 521 | 522 | /** 523 | * malloc - Allocate dynamic memory 524 | * 525 | * @desc malloc() allocates size bytes and returns a pointer to the allocated memory. The memory is not cleared. If 526 | * size is 0, then malloc() returns either NULL, or a unique pointer value that can later be successfully passed 527 | * to free(). 528 | * @return malloc(), the value returned is a pointer to the allocated memory, which is suitably aligned for any kind of 529 | * variable, or NULL if the request fails. 530 | */ 531 | void *malloc(size_t size){ 532 | size_t nbytes = size; 533 | Header *p, *prevp; 534 | size_t nunits; 535 | 536 | nunits = (nbytes+sizeof(Header)-1)/sizeof(header) + 1; 537 | if ((prevp = freep) == NULL) { /* no free list yet */ 538 | base.s.ptr = freeptr = prevptr = &base; 539 | base.s.size = 0; 540 | } 541 | for (p = prevp->s.ptr; ; prevp = p, p = p->s.ptr) { 542 | if (p->s.size >= nunits) { /* big enough */ 543 | if (p->s.size == nunits) /* exactly */ 544 | prevp->s.ptr = p->s.ptr; 545 | else { /* allocate tail end */ 546 | p->s.size -= nunits; 547 | p += p->s.size; 548 | p->s.size = nunits; 549 | } 550 | freep = prevp; 551 | return (void *)(p+1); 552 | } 553 | if (p == freep) /* wrapped around free list */ 554 | if ((p = morecore(nunits)) == NULL) 555 | return NULL; /* none left */ 556 | } 557 | } 558 | 559 | /** 560 | * free - Free dynamic memory 561 | * 562 | * @desc free() frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), 563 | * calloc() or realloc(). Otherwise, or if free(ptr) has already been called before, undefined behavior occurs. 564 | * If ptr is NULL, no operation is performed. 565 | * @return free() returns no value 566 | */ 567 | void free(void *ptr){ 568 | Header *bp, *p; 569 | void *ap = ptr; 570 | 571 | bp = (Header *)ap - 1; /* point to block header */ 572 | for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) 573 | if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) 574 | break; /* freed block at start or end of arena */ 575 | if (bp + bp->size == p->s.ptr) { /* join to upper nbr */ 576 | bp->s.size += p->s.ptr->s.size; 577 | bp->s.ptr = p->s.ptr->s.ptr; 578 | } else 579 | bp->s.ptr = p->s.ptr; 580 | if (p + p->size == bp) { /* join to lower nbr */ 581 | p->s.size += bp->s.size; 582 | p->s.ptr = bp->s.ptr; 583 | } else 584 | p->s.ptr = bp; 585 | freep = p; 586 | } 587 | 588 | /** 589 | * calloc - Allocate dynamic memory 590 | * 591 | * @desc calloc() allocates memory for an array of nmemb elements of size bytes each and returns a pointer to the allo- 592 | * cated memory. The memory is set to zero. If nmemb or size is 0, then calloc() returns either NULL, or a 593 | * unique pointer value that can later be successfully passed to free(). 594 | * @return the value returned is a pointer to the allocated memory, which is suitably aligned for any kind of variable, 595 | * or NULL if the request fails. 596 | */ 597 | void *calloc(size_t nmemb, size_t size){ 598 | void *ptr; 599 | 600 | ptr = malloc(nmemb * size); 601 | if (ptr) 602 | memset(ptr, '\0', nmemb * size); 603 | return ptr; 604 | } 605 | 606 | 607 | /** 608 | * realloc - Allocate dynamic memory 609 | * 610 | * @desc realloc() changes the size of the memory block pointed to by ptr to size bytes. The contents will be unchanged 611 | * to the minimum of the old and new sizes; newly allocated memory will be uninitialized. If ptr is NULL, the 612 | * call is equivalent to malloc(size); if size is equal to zero, the call is equivalent to free(ptr). Unless ptr 613 | * is NULL, it must have been returned by an earlier call to malloc(), calloc() or realloc(). If the area pointed 614 | * to was moved, a free(ptr) is done. 615 | * @return realloc() returns a pointer to the newly allocated memory, which is suitably aligned for any kind of variable 616 | * and may be different from ptr, or NULL if the request fails. If size was equal to 0, either NULL or a pointer 617 | * suitable to be passed to free() is returned. If realloc() fails the original block is left untouched; it is 618 | * not freed or moved. 619 | */ 620 | void *realloc(void *ptr, size_t size){ 621 | Header *bp; 622 | void *new_ptr; 623 | size_t old_size; 624 | 625 | if (ptr == NULL) 626 | return malloc(size); 627 | bp = (Header *)ptr - 1; /* point to block header */ 628 | old_size = sizeof(Header) * (bp->s.size - 1); 629 | new_ptr = malloc(size); 630 | if (new_ptr == NULL) { 631 | return NULL; 632 | } 633 | if (old_size <= size) { 634 | memcpy(new_ptr, ptr, old_size); 635 | } else { 636 | memcpy(new_ptr, ptr, size); 637 | } 638 | free(ptr); 639 | return new_ptr; 640 | } 641 | 642 | 643 | 644 | -------------------------------------------------------------------------------- /src/stdlib.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tima Standard ANSI C based Library 3 | * 4 | * Copyright (C) 2008 heiyeluren. All rights reserved. 5 | * 6 | * Open-source ANSI C library powered by TieMa(TIMA) Studio. 7 | * 8 | * Use and distribution licensed under the BSD license. See 9 | * the LICENSE file for full text. 10 | * 11 | * To learn more open-source code, http://heiyeluren.googlecode.com 12 | * My blog: http://blog.csdn.net/heiyeshuwu 13 | * 14 | * $Id: stdlib.c 2008-11-09 23:31 heiyeluren $ 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | 23 | /** 24 | * for string conversion function 25 | */ 26 | #ifndef ULONG_MAX 27 | #define ULONG_MAX ((unsigned long)(~0L)) /* 0xFFFFFFFF */ 28 | #endif 29 | 30 | #ifndef LONG_MAX 31 | #define LONG_MAX ((long)(ULONG_MAX >> 1)) /* 0x7FFFFFFF */ 32 | #endif 33 | 34 | #ifndef LONG_MIN 35 | #define LONG_MIN ((long)(~LONG_MAX)) /* 0x80000000 */ 36 | #endif 37 | 38 | /** 39 | * for rand & srand seed 40 | */ 41 | #ifndef RAND_MAX 42 | #define RAND_MAX 1103515245 43 | #endif 44 | 45 | unsigned long int __rand_next__ = 1; 46 | 47 | /** 48 | * for memory control function 49 | */ 50 | #define NALLOC 1024 /* minimum #units to request */ 51 | 52 | typedef long Align; /* for alignment to long boundary */ 53 | union header { /* block header */ 54 | struct { 55 | union header *ptr; /* next block if on free list */ 56 | size_t size; /* size of this block */ 57 | } s; 58 | Align x; /* force alignment of blocks */ 59 | }; 60 | typedef union header Header; 61 | 62 | static Header base; /* empty list to get started */ 63 | static Header *freep = NULL; /* start of free list */ 64 | 65 | 66 | /** 67 | * String conversion function define 68 | */ 69 | double atof(const char *nptr); 70 | int atoi(const char *nptr); 71 | long atol(const char *nptr); 72 | //double strtod(const char *nptr, char **endptr); 73 | double strtod(char *str, char **ptr); 74 | long int strtol(const char *nptr, char **endptr,int base); 75 | unsigned long int strtoul(const char *nptr, char **endptr, int base); 76 | 77 | 78 | /** 79 | * Math function define 80 | */ 81 | int abs(int j); 82 | long int labs(long int j); 83 | long long int llabs(long long int j); 84 | 85 | 86 | /** 87 | * Data Structure and Algorithm function define 88 | */ 89 | void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar) (const void*, const void*)); 90 | void qsort(void * base, size_t nmemb,size_t size, int ( * compar)(const void *, const void *)); 91 | void srand(unsigned int seed); 92 | int rand(void); 93 | int rand_r(unsigned int *seed); 94 | 95 | 96 | /** 97 | * Memory control function define 98 | */ 99 | void *calloc(size_t nmemb, size_t size); 100 | void *malloc(size_t size); 101 | void free(void *ptr); 102 | void *realloc(void *ptr, size_t size); 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /src/string.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Tima Standard ANSI C based Library 3 | * 4 | * Copyright (C) 2008 heiyeluren. All rights reserved. 5 | * 6 | * Open-source ANSI C library powered by TieMa(TIMA) Studio. 7 | * 8 | * Use and distribution licensed under the BSD license. See 9 | * the LICENSE file for full text. 10 | * 11 | * To learn more open-source code, http://heiyeluren.googlecode.com 12 | * My blog: http://blog.csdn.net/heiyeshuwu 13 | * 14 | * $Id: string.c 2008-11-08 23:46 heiyeluren $ 15 | */ 16 | 17 | #include "string.h" 18 | 19 | 20 | 21 | /** 22 | * strlen - calculate the length of a string 23 | */ 24 | size_t strlen(const char *s){ 25 | size_t n; 26 | 27 | for(n = 0; *s++; n++) ; 28 | return n; 29 | } 30 | 31 | /** 32 | * strcat - concatenate two strings 33 | */ 34 | char *strcat(char *dest, const char *src){ 35 | char *ptr = dest; 36 | 37 | while( *dest++ ) ; 38 | for( *dest--; *dest++ = *src++; ) ; 39 | return ptr; 40 | } 41 | 42 | /** 43 | * stnrcat - concatenate two strings 44 | */ 45 | char *strncat(char *dest, const char *src, size_t n){ 46 | char *ptr = dest; 47 | 48 | while( *dest++ ); 49 | for( --dest; n-- && (*dest++ = *src++); ) ; 50 | *dest = 0; 51 | return ptr; 52 | } 53 | 54 | /** 55 | * strcpy - copy a string 56 | */ 57 | char *strcpy(char *dest, const char *src){ 58 | char *ptr = dest; 59 | 60 | while( *dest++ = *src++ ) ; 61 | *dest = 0; 62 | return ptr; 63 | } 64 | 65 | /** 66 | * strncpy - copy a string 67 | */ 68 | char *strncpy(char *dest, const char *src, size_t n){ 69 | char *ptr = dest; 70 | 71 | while(n-- && (*dest++ = *src++)) ; 72 | *dest = 0; 73 | return ptr; 74 | } 75 | 76 | /** 77 | * strdup - duplicate a string 78 | * 79 | * @return string pointer can be freed with free() 80 | */ 81 | char *strdup(const char *s){ 82 | char *ptr, *dst; 83 | 84 | ptr = dst = (char *)malloc(strlen(s)+1); 85 | while(*dst++=*s++) ; 86 | *dst = 0; 87 | return ptr; 88 | } 89 | 90 | /** 91 | * strndup - duplicate a string 92 | * 93 | * @return string pointer can be freed with free() 94 | */ 95 | char *strndup(const char *s, size_t n){ 96 | char *ptr, *dst; 97 | 98 | ptr = dst = (char *)malloc( strlen(s) + 1 ); 99 | while(n-- && (*dst++ = *s++)) ; 100 | *dst = 0; 101 | return ptr; 102 | } 103 | 104 | /** 105 | * strcmp - compare two strings 106 | */ 107 | int strcmp(const char *s1, const char *s2){ 108 | int s; 109 | 110 | while( (s = *s1++ - *s2++) == 0 ) ; 111 | return s; 112 | } 113 | 114 | /** 115 | * strcmp - compare two strings 116 | */ 117 | int strncmp(const char *s1, const char *s2, size_t n){ 118 | int s; 119 | 120 | while( n-- && (s = *s1++ - *s2++) == 0 ) ; 121 | return s; 122 | } 123 | 124 | /** 125 | * strcasecmp - compare two strings ignoring case 126 | */ 127 | int strcasecmp(const char *s1, const char *s2){ 128 | char c1, c2; 129 | int s; 130 | 131 | for(;;){ 132 | c1 = *s1++; 133 | c2 = *s2++; 134 | c1 = (c1>='A' && c1<='Z') ? c1 + ('a' - 'A') : c1; 135 | c2 = (c2>='A' && c2<='Z') ? c2 + ('a' - 'A') : c2; 136 | if ((s = c1 - c2) != 0) 137 | break; 138 | if (c1==0 || c2==0){ 139 | s = c1 - c2; 140 | break; 141 | } 142 | } 143 | return s; 144 | } 145 | 146 | /** 147 | * strncasecmp - compare two strings ignoring case 148 | */ 149 | int strncasecmp(const char *s1, const char *s2, size_t n){ 150 | int s; 151 | char c1, c2; 152 | 153 | while (n--){ 154 | c1 = *s1++; 155 | c2 = *s2++; 156 | c1 = (c1>='A' && c1<='Z') ? c1 + ('a' - 'A') : c1; 157 | c2 = (c2>='A' && c2<='Z') ? c2 + ('a' - 'A') : c2; 158 | if ((s = c1 - c2) != 0) 159 | break; 160 | if (c1==0 || c2==0){ 161 | s = c1 - c2; 162 | break; 163 | } 164 | } 165 | return s; 166 | } 167 | 168 | /** 169 | * strcoll - compare two strings using the current locale 170 | */ 171 | int strcoll(const char *s1, const char *s2){ 172 | //collate table (ASCII 0-255) 173 | unsigned char coll[256] = { 174 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 175 | 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 176 | 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 177 | 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 178 | 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 179 | 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 180 | 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 181 | 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 182 | 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 183 | 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 184 | 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 185 | 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 186 | 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 187 | 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 188 | 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 189 | 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff 190 | }; 191 | 192 | while (coll[(unsigned char)*s1] == coll[(unsigned char)*s2]){ 193 | if (*s1 == 0) return 0; 194 | s1++, s2++; 195 | } 196 | return coll[(unsigned char)*s1] - coll[(unsigned char)*s2]; 197 | } 198 | 199 | 200 | /** 201 | * strchr - locate character in string 202 | * 203 | * @returns a pointer to the first occurrence of the character c in the string s 204 | */ 205 | char *strchr(const char *s, int c){ 206 | for (; *s && *s != (char)c; s++) ; 207 | return ( *s == (char)c ? (char *)s : NULL ); 208 | } 209 | 210 | /** 211 | * strrchr - locate character in string 212 | * 213 | * @returns a pointer to the last occurrence of the character c in the string s 214 | */ 215 | char *strrchr(const char *s, int c){ 216 | size_t n; 217 | 218 | for ( n = 0; *s++; n++ ) ; 219 | for ( ; n != 0 && *s != (char)c; s--,n-- ) ; 220 | return ( *s == (char)c ? (char *)s : NULL ); 221 | } 222 | 223 | /** 224 | * index - locate character in string 225 | * 226 | * @returns a pointer to the first occurrence of the character c in the string s 227 | */ 228 | char *index(const char *s, int c){ 229 | if ( (char)c == '\0'){ 230 | while(*s++) ; 231 | return (char *)s; 232 | } 233 | for ( ; *s && *s != (char)c; s++ ) ; 234 | return ( *s == (char)c ? (char *)s : NULL ); 235 | } 236 | 237 | /** 238 | * index - locate character in string 239 | * 240 | * @returns a pointer to the last occurrence of the character c in the string s 241 | */ 242 | char *rindex(const char *s, int c){ 243 | size_t n; 244 | 245 | if ( (char)c == '\0'){ 246 | while(*s++) ; 247 | return (char *)s; 248 | } 249 | for ( n = 0; *s++; n++ ) ; 250 | for (; n != 0 && *s != (char)c; s--,n--) ; 251 | return ( *s == (char)c ? (char *)s : NULL ); 252 | } 253 | 254 | /** 255 | * strpbrk - search a string for any of a set of characters 256 | * 257 | * @desc The function locates the first occurrence in the string s of any of the characters in 258 | * the string accept. 259 | */ 260 | char *strpbrk(const char *s, const char *accept){ 261 | const char *s1, *s2; 262 | 263 | for (s1 = s; *s1; s1++){ 264 | for (s2 = accept; *s2; s2++){ 265 | if (*s1 == *s2){ 266 | return (char *)s1; 267 | } 268 | } 269 | } 270 | return NULL; 271 | } 272 | 273 | /** 274 | * strspn - search a string for a set of characters 275 | * 276 | * @desc The function calculates the length of the initial segment of s which consists entirely of 277 | * characters in accept. 278 | */ 279 | size_t strspn(const char *s, const char * accept){ 280 | const char *s1, *s2; 281 | short flag; 282 | size_t n; 283 | 284 | 285 | for (n = 0,s1 = s; *s1; s1++){ 286 | flag = 0; 287 | for (s2 = accept; *s2; s2++){ 288 | if (*s1 == *s2){ 289 | ++n, flag = 1; 290 | } 291 | } 292 | if (!flag) break; 293 | } 294 | return n; 295 | } 296 | 297 | /** 298 | * strcspn - search a string for a set of characters 299 | * 300 | * @desc The function calculates the length of the initial segment of s which consists entirely of 301 | * characters not in reject. 302 | */ 303 | size_t strcspn(const char *s, const char *reject){ 304 | const char *s1, *s2; 305 | short flag; 306 | size_t n; 307 | 308 | for (n = 0, s1 = s; *s1; s1++){ 309 | flag = 0; 310 | for (s2 = reject; *s2; s2++){ 311 | if (*s1 == *s2){ 312 | flag = 1; 313 | } 314 | } 315 | if (flag) break; 316 | n++; 317 | } 318 | return n; 319 | } 320 | 321 | /** 322 | * strstr - locate a substring 323 | * 324 | * @desc The function finds the first occurrence of the substring needle in the string haystack. 325 | * The terminat-ing '\0' characters are not compared. 326 | */ 327 | 328 | char *strstr(const char *haystack, const char *needle){ 329 | const char *s1, *s2; 330 | size_t n, len; 331 | 332 | for (len = 0, s2 = needle; *s2++; ++len) ; 333 | for (s1 = haystack; *s1; s1++){ 334 | for (n = 0, s2 = needle; *s2 && *s1 == *s2; s1++, s2++, n++) ; 335 | if (len == n) return (char *)s1; 336 | } 337 | return NULL; 338 | } 339 | 340 | /** 341 | * strtok - extract tokens from strings 342 | * 343 | * @return The functions return a pointer to the next token, or NULL if there are no more tokens. 344 | */ 345 | char *strtok(char *str, const char *delim){ 346 | static char *tok; 347 | 348 | if (str == NULL) str = tok; 349 | str += strspn(str, delim); 350 | if (*str == '\0') return NULL; 351 | tok = str + strcspn(str, delim); 352 | if (*tok != '\0') *(tok)++ = '\0'; 353 | return str; 354 | } 355 | 356 | /** 357 | * memcpy - copy memory area 358 | * 359 | * @desc The function copies n bytes from memory area src to memory area dest. The memory areas should not 360 | * overlap. Use memmove(3) if the memory areas do overlap. 361 | * @return The function returns a pointer to dest. 362 | */ 363 | void *memcpy(void *dest, const void *src, size_t n){ 364 | char *s1, *s2; 365 | for (s1 = (char *)dest, s2 = (char *)src; n--;){ 366 | *s1++ = *s2++; 367 | } 368 | return (void *)dest; 369 | } 370 | 371 | /** 372 | * memccpy - copy memory area 373 | * 374 | * @desc The function copies no more than n bytes from memory area src to memory area dest, stopping when the 375 | * character c is found. 376 | * @return The function returns a pointer to dest. 377 | */ 378 | void *memccpy(void *dest, const void *src, int c, size_t n){ 379 | char *s1, *s2; 380 | for (s1 = (char *)dest, s2 = (char *)src; n--;){ 381 | if ((*s1++ = *s2++) == (char)c){ 382 | return (void *)s1; 383 | } 384 | } 385 | return NULL; 386 | } 387 | 388 | /** 389 | * memmove - copy memory area 390 | * 391 | * @desc The function copies n bytes from memory area src to memory area dest. The memory areas may overlap: 392 | * copying takes place as though the bytes in src are first copied into a temporary array that does not overlap 393 | * src or dst, and the bytes are then copied from the temporary array to dest. 394 | * @return The function returns a pointer to dest. 395 | */ 396 | void *memmove(void *dest, const void *src, size_t n){ 397 | size_t i; 398 | 399 | if (src >= dest || (void *)((char *)src + n) <= dest) { 400 | return memcpy(dest, src, n); 401 | } else { 402 | for (i = n; i > 0; i--) { 403 | ((char *)dest)[i - 1] = ((const char *)src)[i - 1]; 404 | } 405 | return dest; 406 | } 407 | } 408 | 409 | 410 | /** 411 | * memset - fill memory with a constant byte 412 | * 413 | * @desc The function fills the first n bytes of the memory area pointed to by s with the constant byte c. 414 | * @return The function returns a pointer to the memory area s. 415 | */ 416 | void *memset(void *s , int c, size_t n){ 417 | unsigned char *mem = s; 418 | while (n--){ 419 | *mem++ = (unsigned char)c; 420 | } 421 | return (void *)s; 422 | } 423 | 424 | /** 425 | * memcmp - compare memory areas 426 | * 427 | * @desc The function compares the first n bytes of the memory areas s1 and s2. It returns an integer less 428 | * than,equal to, or greater than zero if s1 is found, respectively, to be less than, to match, or be greater 429 | * than s2. 430 | * @return The function returns an integer less than, equal to, or greater than zero if the first n bytes of s1 431 | * is found, respectively, to be less than, to match, or be greater than the first n bytes of s2. 432 | */ 433 | int memcmp(const void *s1, const void *s2, size_t n){ 434 | const char *ts1, *ts2; 435 | for (ts1 = (char *)s1, ts2 = (char *)s2; --n && (*ts1 == *ts2); ts1++, ts2++) ; 436 | return (*ts1 - *ts2); 437 | } 438 | 439 | /** 440 | * memchr - scan memory for a character 441 | * 442 | * @desc The function scans the first n bytes of the memory area pointed to by s for the character c. The 443 | * first byte to match c (interpreted as an unsigned character) stops the operation. 444 | * @return The functions return a pointer to the matching byte or NULL if the character does not occur in 445 | * the given memory area. 446 | */ 447 | void *memchr(const void *s, int c, size_t n){ 448 | const char *s1 = s; 449 | while (n--){ 450 | if ((*s1++ == (char)c)){ 451 | return (void *)s1; 452 | } 453 | } 454 | return NULL; 455 | } 456 | 457 | /** 458 | * memrchr - scan memory for a character 459 | * 460 | * @desc The function is like the function, except that it searches backwards from the end of the n 461 | * bytes pointed to by s instead of forwards from the front. 462 | * @return The functions return a pointer to the matching byte or NULL if the character does not occur in 463 | * the given memory area. 464 | */ 465 | void *memrchr(const void *s, int c, size_t n){ 466 | const char *s1; 467 | for (s1 = s, s1 += n; n--;){ 468 | if ((*s1-- == (char)c)){ 469 | return (void *)s1; 470 | } 471 | } 472 | return NULL; 473 | } 474 | 475 | /** 476 | * bzero - write zero-valued bytes 477 | * 478 | * @desc The function sets the first n bytes of the byte area starting at s to zero (bytes containing '\0'). 479 | */ 480 | void bzero(void *s, int n){ 481 | memset((void *)s, 0, (size_t)n); 482 | } 483 | 484 | /** 485 | * bcopy - copy byte sequence 486 | * 487 | * @desc The function copies n bytes from src to dest. The result is correct, even when both areas overlap. 488 | */ 489 | void bcopy(const void *src, void *dest, int n){ 490 | memcpy((void *)dest, (void *)src, (size_t)n); 491 | } 492 | 493 | /** 494 | * bcmp - compare byte sequences 495 | * 496 | * @desc The function compares the two byte sequences s1 and s2 of length n each. If they are equal, and in 497 | * particular if n is zero, bcmp() returns 0. Otherwise it returns a non-zero result. 498 | * @return The function returns 0 if the byte sequences are equal, otherwise a non-zero result is returned. 499 | */ 500 | int bcmp(const void *s1, const void *s2, int n){ 501 | return memcmp((void *)s1, (void *)s2, (size_t)n); 502 | } 503 | 504 | 505 | -------------------------------------------------------------------------------- /src/string.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tima Standard ANSI C based Library 3 | * 4 | * Copyright (C) 2008 heiyeluren. All rights reserved. 5 | * 6 | * Open-source ANSI C library powered by TieMa(TIMA) Studio. 7 | * 8 | * Use and distribution licensed under the BSD license. See 9 | * the LICENSE file for full text. 10 | * 11 | * To learn more open-source code, http://heiyeluren.googlecode.com 12 | * My blog: http://blog.csdn.net/heiyeshuwu 13 | * 14 | * $Id: string.c 2008-11-08 23:46 heiyeluren $ 15 | */ 16 | 17 | #include 18 | 19 | /** 20 | * string functions define 21 | */ 22 | size_t strlen(const char *s); 23 | char *strcat(char *dest, const char *src); 24 | char *strncat(char *dest, const char *src, size_t n); 25 | char *strcpy(char *dest, const char *src); 26 | char *strncpy(char *dest, const char *src, size_t n); 27 | char *strdup(const char *s); 28 | char *strndup(const char *s, size_t n); 29 | int strcmp(const char *s1, const char *s2); 30 | int strncmp(const char *s1, const char *s2, size_t n); 31 | int strcoll(const char *s1, const char *s2); 32 | char *strchr(const char *s, int c); 33 | char *strrchr(const char *s, int c); 34 | char *index(const char *s, int c); 35 | char *rindex(const char *s, int c); 36 | char *strpbrk(const char *s, const char *accept); 37 | size_t strspn(const char *s, const char *accept); 38 | size_t strcspn(const char *s, const char *reject); 39 | char *strstr(const char *haystack, const char *needle); 40 | char *strtok(char *str, const char *delim); 41 | void *memcpy(void *dest, const void *src, size_t n); 42 | void *memccpy(void *dest, const void *src, int c, size_t n); 43 | void *memmove(void *dest, const void *src, size_t n); 44 | void *memset(void *s, int c, size_t n); 45 | int memcmp(const void *s1, const void *s2, size_t n); 46 | void *memchr(const void *s, int c, size_t n); 47 | void *memrchr(const void *s, int c, size_t n); 48 | void bzero(void *s, size_t n); 49 | void bcopy(const void *src, void *dest, size_t n); 50 | int bcmp(const void *s1, const void *s2, size_t n); 51 | 52 | 53 | --------------------------------------------------------------------------------