#include "ansi.h"

float pow(float x, float n)
{
	if(n == 2) return x * x;
	else return x * pow(x, n - 1);
}

void *malloc(int size)
{
	struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
	char *p = memman_alloc_4k(memman, size + 16);
	if(p != 0) {
		*((int *) p) = size;
		p += 16;
	}
	return p;
}

void free(void *p)
{
	struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
	char *q = p;
	int size;
	if(q != 0) {
		q -= 16;
		size = *((int *) q);
		memman_free_4k(memman, q, size + 16);
	}
}

FILE *fopen(char *filename, char *type)
{
	struct TASK *task = task_now();
	struct FILEINFO *finfo;
	int i;
	struct FILEHANDLE *fh;
	FILE *fp = (FILE *) malloc(sizeof(FILE));
	
	for (i = 0; i < 8; i++) {
		if (task->fhandle[i].buf == 0) {
			break;
		}
	}
	fh = &task->fhandle[i];
	fp->fh = 0;
	if (i < 8) {
		finfo = file_search2(filename,
				(struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224, task->fat);
		if (finfo != 0) {
			fp->fh = (int) fh;
			fh->size = finfo->size;
			fh->pos = 0;
			fh->buf = file_loadfile2(finfo->clustno, &fh->size, task->fat);
			fh->finfo = finfo;
			fh->mode = 0;
		} else {
			return 0;
		}
	}
	
	return fp;
}

void fclose(FILE *fp)
{
	fp->fh->buf = 0;
	free(fp);
}

void fseek(FILE *fp, int offset, int orgtype)
{
	switch(orgtype) {
	case SEEK_SET:
		fp->fh->pos = offset;
	case SEEK_END:
		fp->fh->pos = fp->fh->size + offset;
	case SEEK_CUR:
		fp->fh->pos += offset;
	}
}

void fgets(char *buffer, int size, FILE *fp)
{
	int i;
	struct FILEHANDLE *fh = fp->fh;
	int lfb = 0;
	
	for (i = 0; i < size; i++) {
		if (fh->pos == fh->size) {
			break;
		}
		if(fh->buf[fh->pos] != 0x0d && fh->buf[fh->pos] != 0x0a) buffer[i] = fh->buf[fh->pos];
		else {
			lfb = 1;
			break;
		}
		fh->pos++;
	}
	
	if(lfb == 1) for(;fh->buf[fh->pos] == 0x0d || fh->buf[fh->pos] == 0x0a; fh->pos++);
	
}

int feof(FILE *fp)
{
	return fp->fh->pos == fp->fh->size;
}

/*int atoi(const char *str)
{
	  // NULLかチェック
	  if(!str)return 0;

	  int value = 0;
	  const char *p = str;

	  //  先頭の文字がマイナスだったら、一文字進める
	  if( *p == '-' )p++;

	  //  *p  が  0 から 9	をはみ出したら終了
	  while( *p >= '0' && *p <= '9' )
	  {
			//	valueを10倍
			value *= 10;

			//	文字を正しい整数に直して、一文字進めてvalueに渡す。
			value += *p++ - '0';
	  }

	  //  先頭がマイナスだったら、value をマイナスにする
	  if( *str == '-' )value = -value;

	  return value;
}
*/
int isdigit(char c)
{
	return (c <= '9' && '0' <= c);
}

float strtod(char *s, char **sp)
{
	float value = 0, power = 1;
	int i,sign;

	for (i = 0; s[i] == ' '; i++)
		;
	sign = (s[i] == '-') ? -1 : 1;
	if (s[i] == '+' || s[i] == '-')
		i++;
	for (; isdigit(s[i]); i++)
		value = value * 10 + s[i] - '0';
	if (s[i] == '.')
		i++;
	for (; isdigit(s[i]); i++) {
		value = value * 10 + s[i] - '0';
		power *= 10.0;
	}
	return sign * value / power;
}
