1 /*--------------------------------------------------------------------
2 * TITLE: ANSI C Library
3 * AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
4 * DATE CREATED: 12/17/05
6 * PROJECT: Plasma CPU core
7 * COPYRIGHT: Software placed into the public domain by the author.
8 * Software 'as is' without warranty. Author liable for nothing.
10 * Subset of the ANSI C library
11 *--------------------------------------------------------------------*/
16 char *strcpy(char *dst, const char *src)
28 char *strncpy(char *dst, const char *src, int count)
32 while(count-- > 0 && c)
39 char *strcat(char *dst, const char *src)
53 char *strncat(char *dst, const char *src, int count)
57 while(*dst && --count > 0)
59 while(--count > 0 && c)
66 int strcmp(const char *string1, const char *string2)
71 diff = *string1++ - (c = *string2++);
80 int strncmp(const char *string1, const char *string2, int count)
85 diff = *string1++ - (c = *string2++);
95 char *strstr(const char *string, const char *find)
100 for(i = 0; string[i] == find[i] && find[i]; ++i) ;
102 return (char*)string;
109 int strlen(const char *string)
111 const char *base=string;
113 return string - base - 1;
117 void *memcpy(void *dst, const void *src, unsigned long bytes)
119 if(((uint32)dst | (uint32)src | bytes) & 3)
121 uint8 *Dst = (uint8*)dst, *Src = (uint8*)src;
122 while((int)bytes-- > 0)
127 uint32 *Dst32 = (uint32*)dst, *Src32 = (uint32*)src;
129 while((int)bytes-- > 0)
136 void *memmove(void *dst, const void *src, unsigned long bytes)
138 uint8 *Dst = (uint8*)dst;
139 uint8 *Src = (uint8*)src;
142 while((int)bytes-- > 0)
149 while((int)bytes-- > 0)
156 int memcmp(const void *cs, const void *ct, unsigned long bytes)
158 uint8 *Dst = (uint8*)cs;
159 uint8 *Src = (uint8*)ct;
161 while((int)bytes-- > 0)
163 diff = *Dst++ - *Src++;
171 void *memset(void *dst, int c, unsigned long bytes)
173 uint8 *Dst = (uint8*)dst;
174 while((int)bytes-- > 0)
182 return n>=0 ? n : -n;
186 static uint32 Rand1=0x1f2bcda3;
189 Rand1 = 1664525 * Rand1 + 1013904223; //from D.E. Knuth and H.W. Lewis
194 void srand(unsigned int seed)
200 long strtol(const char *s, char **end, int base)
203 unsigned long ch, value=0, neg=0;
210 if(s[0] == '0' && s[1] == 'x')
215 for(i = 0; i <= 8; ++i)
218 if('0' <= ch && ch <= '9')
220 else if('A' <= ch && ch <= 'Z')
222 else if('a' <= ch && ch <= 'z')
226 value = value * base + ch;
236 int atoi(const char *s)
238 return strtol(s, NULL, 10);
242 char *itoa(int num, char *dst, int base)
244 int digit, negate=0, place;
247 if(base == 10 && num < 0)
253 for(place = 15; place >= 0; --place)
255 digit = (unsigned int)num % (unsigned int)base;
256 if(num == 0 && place < 15 && base == 10 && negate)
262 c = (char)('0' + digit);
264 c = (char)('a' + digit - 10);
266 num = (unsigned int)num / (unsigned int)base;
267 if(num == 0 && negate == 0)
270 strcpy(dst, text + place);
275 int sprintf(char *s, const char *format,
276 int arg0, int arg1, int arg2, int arg3,
277 int arg4, int arg5, int arg6, int arg7)
280 int argc=0, width, length;
281 char f, text[20], fill;
283 argv[0] = arg0; argv[1] = arg1; argv[2] = arg2; argv[3] = arg3;
284 argv[4] = arg4; argv[5] = arg5; argv[6] = arg6; argv[7] = arg7;
296 while('0' <= f && f <= '9')
298 width = width * 10 + f - '0';
311 memset(s, fill, width);
312 itoa(argv[argc++], text, 10);
313 length = (int)strlen(text);
316 strcpy(s + width - length, text);
318 else if(f == 'x' || f == 'f')
320 memset(s, '0', width);
321 itoa(argv[argc++], text, 16);
322 length = (int)strlen(text);
325 strcpy(s + width - length, text);
329 *s++ = (char)argv[argc++];
334 length = strlen((char*)argv[argc]);
337 memset(s, ' ', width - length);
340 strcpy(s, (char*)argv[argc++]);
349 if(f == '\r' && *format == '\n')
357 int sscanf(const char *s, const char *format,
358 int arg0, int arg1, int arg2, int arg3,
359 int arg4, int arg5, int arg6, int arg7)
365 argv[0] = arg0; argv[1] = arg1; argv[2] = arg2; argv[3] = arg3;
366 argv[4] = arg4; argv[5] = arg5; argv[6] = arg6; argv[7] = arg7;
383 *(int*)argv[argc++] = strtol(s, (char**)&s, 10);
385 *(int*)argv[argc++] = strtol(s, (char**)&s, 16);
387 *(char*)argv[argc++] = *s++;
390 ptr = (char*)argv[argc++];
408 /*********************** dump ***********************/
409 void dump(const unsigned char *data, int length)
411 int i, index=0, value;
413 memset(string, 0, sizeof(string));
414 for(i = 0; i < length; ++i)
419 printf("%s\n", string);
421 memset(string, 0, sizeof(string));
425 printf("%2x ", value);
427 string[index] = (char)value;
432 for(; index < 16; ++index)
434 printf("%s\n", string);
436 #endif //INCLUDE_DUMP
440 /*********************** qsort ***********************/
441 static void QsortSwap(char *base, long left, long right, long size)
444 char *ptrLeft, *ptrRight;
445 ptrLeft = base + left * size;
446 ptrRight = base + right * size;
447 for(i = 0; i < size; ++i)
450 ptrLeft[i] = ptrRight[i];
451 ptrRight[i] = (char)temp;
457 static void qsort2(void *base, long left, long right, long size,
458 int (*cmp)(const void *,const void *))
461 char *base2=(char*)base, *pivot;
464 QsortSwap(base2, left, (left + right)/2, size);
466 pivot = &base2[left*size];
467 for(i = left + 1; i <= right; ++i)
469 if(cmp(&base2[i*size], pivot) < 0)
470 QsortSwap(base2, ++last, i, size);
472 QsortSwap(base2, left, last, size);
473 qsort2(base, left, last-1, size, cmp);
474 qsort2(base, last+1, right, size, cmp);
478 void qsort(void *base,
481 int (*cmp)(const void *,const void *))
483 qsort2(base, 0, n-1, size, cmp);
487 void *bsearch(const void *key,
491 int (*cmp)(const void *,const void *))
493 long cond, low=0, high=n-1, mid;
494 char *base2=(char*)base;
497 mid = (low + high)/2;
498 cond = cmp(key, &base2[mid*size]);
504 return &base2[mid * size];
508 #endif //INCLUDE_QSORT
511 #ifdef INCLUDE_TIMELIB
512 /************************* time.h ***********************/
513 #define SEC_PER_YEAR (365L*24*60*60)
514 #define SEC_PER_DAY (24L*60*60)
515 //typedef unsigned long time_t; //start at 1/1/80
517 // int tm_sec; //(0,59)
518 // int tm_min; //(0,59)
519 // int tm_hour; //(0,23)
520 // int tm_mday; //(1,31)
521 // int tm_mon; //(0,11)
522 // int tm_year; //(0,n) from 1900
523 // int tm_wday; //(0,6) calculated
524 // int tm_yday; //(0,365) calculated
525 // int tm_isdst; //hour adjusted for day light savings
527 static const unsigned short DaysUntilMonth[]=
528 {0,31,59,90,120,151,181,212,243,273,304,334,365};
529 static const unsigned short DaysInMonth[]=
530 {31,28,31,30,31,30,31,31,30,31,30,31};
531 static time_t DstTimeIn, DstTimeOut;
534 /* Leap year if divisible by 4. Centenary years should only be
535 leap-years if they were divisible by 400. */
536 static int IsLeapYear(int year)
538 return(((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0));
541 time_t mktime(struct tm *tp)
544 unsigned long days, y, year;
546 days = tp->tm_mday - 1 + DaysUntilMonth[tp->tm_mon] +
547 365 * (tp->tm_year - 80);
548 seconds = (unsigned long)tp->tm_sec + 60L * (tp->tm_min +
549 60L * (tp->tm_hour + 24L * days));
552 year = 1900 + tp->tm_year - (tp->tm_mon < 2);
553 for(y = 1980; y <= year; y += 4)
555 if(y % 100 != 0 || y % 400 == 0)
556 seconds += SEC_PER_DAY;
562 void gmtime_r(const time_t *tp, struct tm *out)
564 time_t seconds, delta, secondsIn=*tp;
566 unsigned long year, month;
569 if(DstTimeIn <= secondsIn && secondsIn < DstTimeOut)
571 secondsIn += 60 * 60;
575 for(year = 0; ; ++year)
577 delta = SEC_PER_YEAR + IsLeapYear(1980 + year) * SEC_PER_DAY;
583 out->tm_year = year + 80;
584 isLeapYear = IsLeapYear(1980 + year);
585 for(month = 0; ; ++month)
587 delta = SEC_PER_DAY * (DaysInMonth[month] + (isLeapYear && (month == 1)));
594 out->tm_mday = seconds / SEC_PER_DAY;
595 out->tm_yday = DaysUntilMonth[month] + out->tm_mday;
596 seconds -= out->tm_mday * SEC_PER_DAY;
598 out->tm_hour = seconds / (60 * 60);
599 seconds -= out->tm_hour * (60 * 60);
600 out->tm_min = seconds / 60;
601 seconds -= out->tm_min * 60;
602 out->tm_sec = seconds;
603 seconds = secondsIn % (SEC_PER_DAY * 7);
604 out->tm_wday = (seconds / SEC_PER_DAY + 2) % 7; /* 1/1/80 is a Tue */
605 //printf("%4.d/%2.d/%2.d:%2.d:%2.d:%2.d\n",
606 // out->tm_year+1900, out->tm_mon+1, out->tm_mday,
607 // out->tm_hour, out->tm_min, out->tm_sec);
611 void gmtimeDst(time_t dstTimeIn, time_t dstTimeOut)
613 DstTimeIn = dstTimeIn;
614 DstTimeOut = dstTimeOut;
618 //DST from 2am on the second Sunday in March to 2am first Sunday in November
619 void gmtimeDstSet(time_t *tp, time_t *dstTimeIn, time_t *dstTimeOut)
621 time_t seconds, timeIn, timeOut;
627 gmtime_r(tp, &tmDate);
628 year = tmDate.tm_year;
630 //March 1, year, 2AM -> second Sunday
631 tmDate.tm_year = year;
637 seconds = mktime(&tmDate);
638 gmtime_r(&seconds, &tmDate);
639 days = 7 - tmDate.tm_wday + 7;
640 *dstTimeIn = timeIn = seconds + days * SEC_PER_DAY;
642 //November 1, year, 2AM -> first Sunday
643 tmDate.tm_year = year;
649 seconds = mktime(&tmDate);
650 gmtime_r(&seconds, &tmDate);
651 days = 7 - tmDate.tm_wday;
652 *dstTimeOut = timeOut = seconds + days * SEC_PER_DAY;
655 DstTimeOut = timeOut;
657 #endif //INCLUDE_TIMELIB