Mercurial > sos > sos
view src/std.c @ 94:191e99dffd6c
Moved some std.h functions to string.h, worked on a simple version of sprintf
sprintf is a very simple version of the C Standard Library version. It should
work for doubles, ints, and strings.
I also added the strlen function.
author | Jonathan Pevarnek <pevarnj@gmail.com> |
---|---|
date | Sat, 14 May 2011 12:54:29 -0400 |
parents | 480f5685b3c2 |
children | d8f21e4a75e3 |
line wrap: on
line source
#include <std.h> #include <string.h> void init_all(u64 __memsize) { init_io_int(); init_console(); malloc_init(__memsize - HEAP_START); } double abs(double num) { if(num < 0) return num*-1; else return num; } char* itoa(s64 n, char *a, unsigned short base) { char *ret = a; if(n < 0) { *a++ = '-'; n *= -1; } char *b = a; if(!n) *b++ = '0'; for(; n; b++) { int temp = n%base; if(temp < 10) *b = '0' + temp; else *b = 'a' + temp - 10; n = n/base; } *b-- = '\0'; for(; a < b; a++, b--) { //reverse char temp = *b; *b = *a; *a = temp; } return ret; } char* ftoa(double x, char *a, unsigned int prec) { char *ret = a; if(x == INF || x == -INF) { strcpy(a, "INF"); } else if(x != x) { //NAN != NAN strcpy(a, "NAN"); } else { s64 n = (s64) x; //integer part double d = abs(x - (double) n); //fractional part; itoa(n, a, 10); if(prec) { //only do the decimal part if decimal parts were asked for while(*a && *++a); //get to the null character from itoa int i; //counter variable for the for loop *a++ = '.'; //put the decimal in place for(i = 0; i < prec; i++) { d *= 10; //the integer part is the decimal digit *a++ = ((int) d) + '0'; //add the integer part of d to the string d -= (int) d; //chop off the integer part } a--; //move back to the last digit while(*a != '.') { if(*a == '0') { a--; continue; } else if(*a > '0' && *a <= '9') { a++; break; } else { sPrint("ERROR: SOMETHING IS VERY WRONG\n"); break; } } *a = '\0'; } } return ret; } s64 atoi(char *a) { short neg = 0; s64 n = 0; if(*a == '-') { neg = 1; a++; } else if(*a == '+') a++; while(*a >= '0' && *a <= '9') n = n*10 + (*a++ - '0'); if(neg) n *= -1; return n; } double atof(char *a) { s64 n = atoi(a); double x = 0; double dec = .1; short neg = 0; if(*a == '-') { neg = 1; a++; } while(*a != '.') { if(!(*a >= '0' && *a <= '9') && *a != '-') return n; a++; } a++; //a will be immediately after the decimal point while(*a >= '0' && *a <= '9') { //goes through the decimal part x += (*a - '0')*dec; dec *= .1; a++; } if(neg) x*=-1; return n + x; } void sPrint(char *a) { char *b = a; while(*b && *++b); do { putline(a, (b - a > CON_LEN)?CON_LEN:(b - a)); a += CON_LEN; } while(a < b); } char* sGet(char *a, unsigned int n) { int length = getline(a, n); a[(length < n)?length:n - 1] = '\0'; return a; } //DYNAMIC MEMORY static Header base; static Header *allocp = NULL; //the location of the last known free block void malloc_init(size_t memSize) { allocp = &base; allocp->size = 0; allocp->next = (void*)HEAP_START; allocp->next->next = &base; allocp->next->size = memSize/sizeof(blockUnit); if((sizeof(blockUnit)%sizeof(u64))) { sPrint("WARNING: MEMORY NOT 8-BYTE ALIGNED\n"); } } void* malloc(size_t size) { if(allocp == NULL) return NULL; size_t nUnits = ((size + sizeof(Header)) + sizeof(blockUnit) - 1)/sizeof(blockUnit); Header *prev = allocp; Header *cur, *temp; for(cur = prev->next;; prev = cur, cur = cur->next) { if(cur->size >= nUnits) { if(cur->size == nUnits) { prev->next = cur->next; } else { temp = cur + nUnits; //This requires sizeof(blockUnit) == sizeof(Header). TODO fix temp->size = cur->size - nUnits; temp->next = cur->next; prev->next = temp; cur->size = nUnits; } allocp = prev; return (void*)(cur + 1); } else if(cur == allocp) { //We went back to the start... return NULL; } } } void free(void *ptr) { Header *toFree = (Header *)ptr - 1; Header *scan; for(scan = allocp; !(toFree > scan && toFree < scan->next); scan = scan->next) if(scan->next < scan && (toFree > scan || toFree < scan->next)) break; toFree->next = scan->next; scan->next = toFree; if(scan + scan->size == toFree) { scan->size += toFree->size; scan->next = toFree->next; toFree = scan; } if(toFree + toFree->size == toFree->next) { toFree->size += toFree->next->size; toFree->next = toFree->next->next; } } void printHeader(Header* head) { char buffer[20]; sPrint("Memory address is: "); sPrint(itoa((intptr_t)head, buffer, 16)); sPrint("\n"); sPrint("The size of the block is: "); sPrint(itoa(head->size, buffer, 10)); sPrint("\n"); sPrint("Next memory address is: "); sPrint(itoa((intptr_t)head->next, buffer, 16)); sPrint("\n\n"); } void printMem() { Header *cur = allocp; do { printHeader(cur); cur = cur->next; } while(cur != allocp); sPrint("PRINTOUT DONE\n\n"); }