#include <types.h>

void *memcpy(void *dst, const void *src, size_t n) {
	void *dstaddr = dst;
	void *max = dst + n;

	if (((u_long)src & 3) != ((u_long)dst & 3)) {
		while (dst < max) {
			*(char *)dst++ = *(char *)src++;
		}
		return dstaddr;
	}

	while (((u_long)dst & 3) && dst < max) {
		*(char *)dst++ = *(char *)src++;
	}

	// copy machine words while possible
	while (dst + 4 <= max) {
		*(uint32_t *)dst = *(uint32_t *)src;
		dst += 4;
		src += 4;
	}

	// finish the remaining 0-3 bytes
	while (dst < max) {
		*(char *)dst++ = *(char *)src++;
	}
	return dstaddr;
}

void *memset(void *dst, int c, size_t n) {
	void *dstaddr = dst;
	void *max = dst + n;
	u_char byte = c & 0xff;
	uint32_t word = byte | byte << 8 | byte << 16 | byte << 24;

	while (((u_long)dst & 3) && dst < max) {
		*(u_char *)dst++ = byte;
	}

	// fill machine words while possible
	while (dst + 4 <= max) {
		*(uint32_t *)dst = word;
		dst += 4;
	}

	// finish the remaining 0-3 bytes
	while (dst < max) {
		*(u_char *)dst++ = byte;
	}
	return dstaddr;
}

size_t strlen(const char *s) {
	int n;

	for (n = 0; *s; s++) {
		n++;
	}

	return n;
}

char *strcpy(char *dst, const char *src) {
	char *ret = dst;

	while ((*dst++ = *src++) != 0) {
	}

	return ret;
}

const char *strchr(const char *s, int c) {
	for (; *s; s++) {
		if (*s == c) {
			return s;
		}
	}
	return 0;
}

int strcmp(const char *p, const char *q) {
	while (*p && *p == *q) {
		p++, q++;
	}

	if ((u_int)*p < (u_int)*q) {
		return -1;
	}

	if ((u_int)*p > (u_int)*q) {
		return 1;
	}

	return 0;
}
//new
char *  strcat (char *dest, const char *src)  
{  
  //通过strcpy来实现strcat函数  
  strcpy (dest + strlen (dest), src);  
  return dest;  
}
int strncmp(const char* str1, const char* str2, int n)
{
	if (!n)   //n=0时，无字符要比，直接return 0
		return 0;
	while (--n && *str1 && *str1 == *str2) //当字符相等且不为’\0‘时比较下个字符，知道n=0比完
	{
		str1++;
		str2++;
	}
	return *str1 - *str2;//字符不相等时，（*str1 - *str2）可以满足返回值正负的需求
}
char* strstr(const char* str1, const char* str2)
{
	if(str1 ==NULL || str2==NULL){
		return str1;
	}
	const char* s1 = str1;
	const char* s2 = str2;
	const char* p = str1;
	while (*p!='\0')
	{
		s1 =p ;
		s2 = str2;
		while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
		{
			return (char*)p;
		}
		p++;
	}
	return NULL;
} 
int isvar(int c) {
	if (isalnum(c)){
		return 1;
	} else if (c == '_') {
		return 1;
	}
	return 0;
}
int isalnum(int c)
{
  if ( (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') ) return 8;

  return 0;
}
int isalpha(int c)
{
  if ( (c>='a' && c<='z') || (c>='A' && c<='Z') ) return 1024;

  return 0;
}

char *strrchr(const char *s, int c)
{
    if(s == NULL)
    {
        return NULL;
    }

    char *p_char = NULL;
    while(*s != '\0')
    {
        if(*s == (char)c)
        {
            p_char = (char *)s;
        }
        s++;
    }

    return p_char;
}
char *strncpy(char *dest, const char *src, size_t n) {
    char *dest_save = dest;
    while (n && *src) {
        *dest++ = *src++;
        n--;
    }
    while (n--) {
        *dest++ = '\0'; // 如果 n 大于 src 字符串的长度，填充剩余位置为空字符
    }
    return dest_save;
}

void* memmove(void* dest, const void* sour, size_t num)
{
	if (dest < sour)
	{
		for (int i = 0; i <= num; i++)
		{
			*((char*)dest + i) = *((char*)sour + i);
		}
		return dest;
	}
	else if (dest > sour)
	{
		for (int i = num; i >=0; i--)
		{
			*((char*)dest + i) = *((char*)sour + i);
		}
		return dest;
	}
	else
	{
		return dest;
	}
}
//合并路径
void merge_path(char* new_dir, const char* prev_dir, const char* next_dir) {
    // 处理绝对路径情况
    if (next_dir[0] == '/') {
        strcpy(new_dir, next_dir);
    } 
    // 处理相对路径拼接
    else {
        strcpy(new_dir, prev_dir);
        size_t len = strlen(new_dir);
        
        // 确保目录结尾有分隔符
        if (len > 0 && new_dir[len - 1] != '/') {
            strcat(new_dir, "/");
        }
        strcat(new_dir, next_dir);
    }
    
    // 移除末尾冗余分隔符（根目录除外）
    size_t len = strlen(new_dir);
    if (len > 1 && new_dir[len - 1] == '/') {
        new_dir[len - 1] = '\0';
    }
    
    // 路径规范化处理 - 修复：使用原始字符串的副本进行处理
    char temp_path[1024];
    strcpy(temp_path, new_dir);  // 创建原始路径的副本
    
    char buf[1024] = {0};      // 结果缓冲区
    int buf_len = 0;            // 缓冲区长度
    
    char *component = temp_path;
    if (*component == '/') {
        // 处理绝对路径起始
        buf[buf_len++] = '/';
        component++;
    }
    
    // 分割路径为组件
    while (*component) {
        char *next_slash = strchr(component, '/');
        int comp_len = next_slash ? next_slash - component : strlen(component);
        
        // 处理当前组件
        if (comp_len == 2 && strncmp(component, "..", 2) == 0) {
            // 处理上级目录：回退一级
            while (buf_len > 0 && buf[buf_len - 1] != '/') {
                buf_len--;
            }
            if (buf_len > 0) buf_len--;  // 移除前一个'/'
        } 
        else if (!(comp_len == 1 && *component == '.')) {
            // 忽略"."，处理其他组件
            if (buf_len > 0 && buf[buf_len - 1] != '/') {
                buf[buf_len++] = '/';  // 添加分隔符
            }
            strncpy(buf + buf_len, component, comp_len);
            buf_len += comp_len;
        }
        
        // 移动到下一个组件
        component = next_slash ? next_slash + 1 : component + comp_len;
    }
    
    // 处理根目录情况
    if (buf_len == 0) {
        strcpy(new_dir, "/");
    } else {
        buf[buf_len] = '\0';
        strcpy(new_dir, buf);
    }
}
//计算" ; "个数
int count_mulline(char* command){
	char * c=command;
	int num=0;
	while(*c!='\0'){
		if(*c==';'){
			num++;
		}
		c++;
	}
	return num;
}
//取出第n+1个指令
void devide_mulline(char* command, char* single, int n) {
    int count = 0;          // 用于计数当前是第几个子串
    char* start = command;  // 当前子串的起始位置
    char* p = command;      // 遍历指针

    // 遍历整个字符串
    while (*p != '\0') {
        if (*p == ';') {
            // 当遇到分号时，检查是否是需要提取的子串
            if (count == n) {
                // 复制当前子串到single
                while (start < p) {
                    *single++ = *start++;
                }
                *single = '\0'; // 添加字符串结束符
                return;
            }
            count++;        // 子串计数增加
            start = p + 1;  // 下一个子串的起始位置
        }
        p++;
    }

    // 处理字符串末尾的情况（最后一个子串）
    if (count == n) {
        // 复制最后一个子串
        while (*start != '\0' && *start != ';') {
            *single++ = *start++;
        }
        *single = '\0';
    } else {
        // 如果n超出范围（即没有足够的子串），返回空字符串
        *single = '\0';
    }
}
