📄 libc.c
字号:
/*-------------------------------------------------------------------- * TITLE: ANSI C Library * AUTHOR: Steve Rhoads (rhoadss@yahoo.com) * DATE CREATED: 12/17/05 * FILENAME: libc.c * PROJECT: Plasma CPU core * COPYRIGHT: Software placed into the public domain by the author. * Software 'as is' without warranty. Author liable for nothing. * DESCRIPTION: * Subset of the ANSI C library *--------------------------------------------------------------------*/#define NO_ELLIPSIS#include "plasma.h"#include "rtos.h"char *strcpy(char *dst, const char *src){ int c; do { c = *dst++ = *src++; } while(c); return dst;}char *strncpy(char *dst, const char *src, int count){ int c=1; while(count-- > 0 && c) c = *dst++ = *src++; *dst = 0; return dst;}char *strcat(char *dst, const char *src){ int c; while(*dst) ++dst; do { c = *dst++ = *src++; } while(c); return dst;}char *strncat(char *dst, const char *src, int count){ int c=1; while(*dst && --count > 0) ++dst; while(--count > 0 && c) c = *dst++ = *src++; *dst = 0; return dst;}int strcmp(const char *string1, const char *string2){ int diff, c; for(;;) { diff = *string1++ - (c = *string2++); if(diff) return diff; if(c == 0) return 0; }}int strncmp(const char *string1, const char *string2, int count){ int diff, c; while(count-- > 0) { diff = *string1++ - (c = *string2++); if(diff) return diff; if(c == 0) return 0; } return 0;}char *strstr(const char *string, const char *find){ int i; for(;;) { for(i = 0; string[i] == find[i] && find[i]; ++i) ; if(find[i] == 0) return (char*)string; if(*string++ == 0) return NULL; }}int strlen(const char *string){ const char *base=string; while(*string++) ; return string - base - 1;}void *memcpy(void *dst, const void *src, unsigned long bytes){ uint8 *Dst = (uint8*)dst; uint8 *Src = (uint8*)src; while((int)bytes-- > 0) *Dst++ = *Src++; return dst;}void *memmove(void *dst, const void *src, unsigned long bytes){ uint8 *Dst = (uint8*)dst; uint8 *Src = (uint8*)src; if(Dst < Src) { while((int)bytes-- > 0) *Dst++ = *Src++; } else { Dst += bytes; Src += bytes; while((int)bytes-- > 0) *--Dst = *--Src; } return dst;}int memcmp(const void *cs, const void *ct, unsigned long bytes){ uint8 *Dst = (uint8*)cs; uint8 *Src = (uint8*)ct; int diff; while((int)bytes-- > 0) { diff = *Dst++ - *Src++; if(diff) return diff; } return 0;}void *memset(void *dst, int c, unsigned long bytes){ uint8 *Dst = (uint8*)dst; while((int)bytes-- > 0) *Dst++ = (uint8)c; return dst;}int abs(int n){ return n>=0 ? n : -n;}static uint32 Rand1=0x1f2bcda3, Rand2=0xdeafbeef, Rand3=0xc5134306;int rand(void){ int shift; Rand1 += 0x13423123 + Rand2; Rand2 += 0x2312fdea + Rand3; Rand3 += 0xf2a12de1; shift = Rand3 & 31; Rand1 = (Rand1 << (32 - shift)) | (Rand1 >> shift); Rand3 ^= Rand1; shift = (Rand3 >> 8) & 31; Rand2 = (Rand2 << (32 - shift)) | (Rand2 >> shift); return Rand1;}void srand(unsigned int seed){ Rand1 = seed;}long strtol(const char *s, const char **end, int base){ int i; unsigned long ch, value=0, neg=0; if(s[0] == '-') { neg = 1; ++s; } if(s[0] == '0' && s[1] == 'x') { base = 16; s += 2; } for(i = 0; i <= 8; ++i) { ch = *s++; if('0' <= ch && ch <= '9') ch -= '0'; else if('A' <= ch && ch <= 'Z') ch = ch - 'A' + 10; else if('a' <= ch && ch <= 'z') ch = ch - 'a' + 10; else break; value = value * base + ch; } if(end) *end = s - 1; if(neg) value = -(int)value; return value;}int atoi(const char *s){ return strtol(s, NULL, 10);}char *itoa(int num, char *dst, int base){ int digit, negate=0, place; char c, text[20]; if(base == 10 && num < 0) { num = -num; negate = 1; } text[16] = 0; for(place = 15; place >= 0; --place) { digit = (unsigned int)num % (unsigned int)base; if(num == 0 && place < 15 && base == 10 && negate) { c = '-'; negate = 0; } else if(digit < 10) c = (char)('0' + digit); else c = (char)('a' + digit - 10); text[place] = c; num = (unsigned int)num / (unsigned int)base; if(num == 0 && negate == 0) break; } strcpy(dst, text + place); return dst;}int sprintf(char *s, const char *format, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7){ int argv[8]; int argc=0, width, length; char f, text[20], fill; argv[0] = arg0; argv[1] = arg1; argv[2] = arg2; argv[3] = arg3; argv[4] = arg4; argv[5] = arg5; argv[6] = arg6; argv[7] = arg7; for(;;) { f = *format++; if(f == 0) return argc; else if(f == '%') { width = 0; fill = ' '; f = *format++; while('0' <= f && f <= '9') { width = width * 10 + f - '0'; f = *format++; } if(f == '.') { fill = '0'; f = *format++; } if(f == 0) return argc; if(f == 'd') { memset(s, fill, width); itoa(argv[argc++], text, 10); length = (int)strlen(text); if(width < length) width = length; strcpy(s + width - length, text); } else if(f == 'x' || f == 'f') { memset(s, '0', width); itoa(argv[argc++], text, 16); length = (int)strlen(text); if(width < length) width = length; strcpy(s + width - length, text); } else if(f == 'c') { *s++ = (char)argv[argc++]; *s = 0; } else if(f == 's') { length = strlen((char*)argv[argc]); if(width > length) { memset(s, ' ', width - length); s += width - length; } strcpy(s, (char*)argv[argc++]); } s += strlen(s); } else if(f == '\\') { f = *format++; if(f == 0) return argc; else if(f == 'n') *s++ = '\n'; else if(f == 'r') *s++ = '\r'; else if(f == 't') *s++ = '\t'; } else { *s++ = f; } *s = 0; }}int sscanf(const char *s, const char *format, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7){ int argv[8]; int argc=0; char f, *ptr; argv[0] = arg0; argv[1] = arg1; argv[2] = arg2; argv[3] = arg3; argv[4] = arg4; argv[5] = arg5; argv[6] = arg6; argv[7] = arg7; for(;;) { if(*s == 0) return argc; f = *format++; if(f == 0) return argc; else if(f == '%') { while(isspace(*s)) ++s; f = *format++; if(f == 0) return argc; if(f == 'd') *(int*)argv[argc++] = strtol(s, &s, 10); else if(f == 'x') *(int*)argv[argc++] = strtol(s, &s, 16); else if(f == 'c') *(char*)argv[argc++] = *s++; else if(f == 's') { ptr = (char*)argv[argc++]; while(!isspace(*s)) *ptr++ = *s++; *ptr = 0; } } else { if(f == '\\') { f = *format++; if(f == 0) return argc; else if(f == 'n') f = '\n'; else if(f == 'r') f = '\r'; else if(f == 't') f = '\t'; } while(*s && *s != f) ++s; if(*s) ++s; } }}#ifdef INCLUDE_DUMP/*********************** dump ***********************/void dump(const unsigned char *data, int length){ int i, index=0, value; char string[80]; memset(string, 0, sizeof(string)); for(i = 0; i < length; ++i) { if((i & 15) == 0) { if(strlen(string)) printf("%s\n", string); printf("%4x ", i); memset(string, 0, sizeof(string)); index = 0; } value = data[i]; printf("%2x ", value); if(isprint(value)) string[index] = (char)value; else string[index] = '.'; ++index; } for(; index < 16; ++index) printf(" "); printf("%s\n", string);}#endif //INCLUDE_DUMP#ifdef INCLUDE_QSORT#define QSORT_SIZE 256/*********************** qsort ***********************/static void QsortSwap(char *base, long left, long right, long size){ char buffer[QSORT_SIZE]; memcpy(buffer, &base[left*size], size); memcpy(&base[left*size], &base[right*size], size); memcpy(&base[right*size], buffer, size);}//Modified from K&Rstatic void qsort2(void *base, long left, long right, long size, int (*cmp)(const void *,const void *)){ int i, last; char *base2=(char*)base, *pivot; if(left >= right) return; QsortSwap(base2, left, (left + right)/2, size); last = left; pivot = &base2[left*size]; for(i = left + 1; i <= right; ++i) { if(cmp(&base2[i*size], pivot) < 0) QsortSwap(base2, ++last, i, size); } QsortSwap(base2, left, last, size); qsort2(base, left, last-1, size, cmp); qsort2(base, last+1, right, size, cmp);}void qsort(void *base, long n, long size, int (*cmp)(const void *,const void *)){ if(size > QSORT_SIZE) { printf("qsort_error"); return; } qsort2(base, 0, n-1, size, cmp); }void *bsearch(const void *key, const void *base, long n, long size, int (*cmp)(const void *,const void *)){ long cond, low=0, high=n-1, mid; char *base2=(char*)base; while(low <= high) { mid = (low + high)/2; cond = cmp(key, &base2[mid*size]); if(cond < 0) high = mid - 1; else if(cond > 0) low = mid + 1; else return &base2[mid * size]; } return NULL;}#endif //INCLUDE_QSORT#ifdef INCLUDE_TIMELIB/************************* time.h ***********************/#define SEC_PER_YEAR (365L*24*60*60)#define SEC_PER_DAY (24L*60*60)//typedef unsigned long time_t; //start at 1/1/80//struct tm {// int tm_sec; //(0,59)// int tm_min; //(0,59)// int tm_hour; //(0,23)// int tm_mday; //(1,31)// int tm_mon; //(0,11)// int tm_year; //(0,n) from 1900// int tm_wday; //(0,6) calculated// int tm_yday; //(0,365) calculated// int tm_isdst; //hour adjusted for day light savings//};static const unsigned short DaysUntilMonth[]= {0,31,59,90,120,151,181,212,243,273,304,334,365}; static const unsigned short DaysInMonth[]= {31,28,31,30,31,30,31,31,30,31,30,31};static time_t DstTimeIn, DstTimeOut;/* Leap year if divisible by 4. Centenary years should only be leap-years if they were divisible by 400. */static int IsLeapYear(int year){ return(((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0));}time_t mktime(struct tm *tp){ time_t seconds; unsigned long days, y, year; days = tp->tm_mday - 1 + DaysUntilMonth[tp->tm_mon] + 365 * (tp->tm_year - 80); seconds = (unsigned long)tp->tm_sec + 60L * (tp->tm_min + 60L * (tp->tm_hour + 24L * days)); if(tp->tm_isdst) seconds -= 60 * 60; year = 1900 + tp->tm_year - (tp->tm_mon < 2); for(y = 1980; y <= year; y += 4) { if(y % 100 != 0 || y % 400 == 0) seconds += SEC_PER_DAY; } return seconds;}void gmtime_r(const time_t *tp, struct tm *out){ time_t seconds, delta, secondsIn=*tp; int isLeapYear; unsigned long year, month; out->tm_isdst = 0; if(DstTimeIn <= secondsIn && secondsIn < DstTimeOut) { secondsIn += 60 * 60; out->tm_isdst = 1; } seconds = secondsIn; for(year = 0; ; ++year) { delta = SEC_PER_YEAR + IsLeapYear(1980 + year) * SEC_PER_DAY; if(seconds >= delta) seconds -= delta; else break; } out->tm_year = year + 80; isLeapYear = IsLeapYear(1980 + year); for(month = 0; ; ++month) { delta = SEC_PER_DAY * (DaysInMonth[month] + (isLeapYear && (month == 1))); if(seconds >= delta) seconds -= delta; else break; } out->tm_mon = month; out->tm_mday = seconds / SEC_PER_DAY; out->tm_yday = DaysUntilMonth[month] + out->tm_mday; seconds -= out->tm_mday * SEC_PER_DAY; ++out->tm_mday; out->tm_hour = seconds / (60 * 60); seconds -= out->tm_hour * (60 * 60); out->tm_min = seconds / 60; seconds -= out->tm_min * 60; out->tm_sec = seconds; seconds = secondsIn % (SEC_PER_DAY * 7); out->tm_wday = (seconds / SEC_PER_DAY + 2) % 7; /* 1/1/80 is a Tue */ //printf("%4.d/%2.d/%2.d:%2.d:%2.d:%2.d\n", // out->tm_year+1900, out->tm_mon+1, out->tm_mday, // out->tm_hour, out->tm_min, out->tm_sec);}void gmtimeDst(time_t dstTimeIn, time_t dstTimeOut){ DstTimeIn = dstTimeIn; DstTimeOut = dstTimeOut;}//DST from 2am on the second Sunday in March to 2am first Sunday in Novembervoid gmtimeDstSet(time_t *tp, time_t *dstTimeIn, time_t *dstTimeOut){ time_t seconds, timeIn, timeOut; struct tm tmDate; int year, days; DstTimeIn = 0; DstTimeOut = 0; gmtime_r(tp, &tmDate); year = tmDate.tm_year; //March 1, year, 2AM -> second Sunday tmDate.tm_year = year; tmDate.tm_mon = 2; tmDate.tm_mday = 1; tmDate.tm_hour = 2; tmDate.tm_min = 0; tmDate.tm_sec = 0; seconds = mktime(&tmDate); gmtime_r(&seconds, &tmDate); days = 7 - tmDate.tm_wday + 7; *dstTimeIn = timeIn = seconds + days * SEC_PER_DAY; //November 1, year, 2AM -> first Sunday tmDate.tm_year = year; tmDate.tm_mon = 10; tmDate.tm_mday = 1; tmDate.tm_hour = 2; tmDate.tm_min = 0; tmDate.tm_sec = 0; seconds = mktime(&tmDate); gmtime_r(&seconds, &tmDate); days = 7 - tmDate.tm_wday; *dstTimeOut = timeOut = seconds + days * SEC_PER_DAY; DstTimeIn = timeIn; DstTimeOut = timeOut;}#endif //INCLUDE_TIMELIB
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -