

#include "stdlib.h"
#include "mystdlib.h"
#include "mystring.h"
#include "bytearray.h"
#include "board.h"
#include "string.h"

/*
*
* 从左向右找到字符串s中首次出现字符c的指针,没找到返回0
* 例如 char *s=str_find_char_right("abcdef",'c')
* s="cdef"
*
*/
const char *str_find_char_right(const char *s,char c)
{
  while(*s){
    if(*s==c) return s;
    s++;
  }
  return 0;
}


/*
*
* 从左向右找到字符串s中首次出现字符c的指针,没找到返回0,
* 指针p是向右检索的终点
* 例如 char *s=str_find_char_right("abcdef",'c')
* s="cdef"
*
*/
const char *str_find_char_right_p(const char *s, const char *const p, char c)
{
  while (*s++)
  {
    if (*s == c) return s;
    if (s >= p) break;
  }
  return 0;
}



/*
*
* 从右向左找到字符串s中首次出现字符c的指针,没找到返回0
* 指针p是向左检索的终点，s检索开始
* char *t="abcdef";
* char *s;
* s=str_find_char_left(t,t+4,'b');
* s="bcdef"
*
*/
const char *str_find_char_left(const char *const p,const char *s,char c)
{
  while(*s--)
  {
    if(*s==c) return s;
    if(s<=p) break;
  }
  return 0;
}


/*
*
* 计算字符串 s 的长度
*
*/
int str_len(const char *s)
{
  int len=0;
  while(*s++) len++;
  return len;
}


/*
*
* 把 s2 中的内容复制到 s1 中，长度为 n
*
*/
void str_memcpy(char *s1,const char *s2,int n)
{
  while(n--)
    *s1++=*s2++;
}





/*
*
* 把 s2 中第一个 c 字符前的字符复制到 s1 中，如果没找到则全部复制，返回复制的字符个数
*
*/
int str_cpystr(char *s1,const char *s2,char c)
{
  int len;
  const char *str=str_find_char_right((char *)s2,c);
  if(str==0) len=str_len(s2);
  else len=str-s2;
  str_memcpy(s1,s2,len);
  s1[len]=0;
  return len;
}




/*
*
* 把整数字符串传化为int,直到遇到非数字字符
*
*/
static int str_ainttoi(const char *s)
{
  int ret=0;
  int sig=1;
  if(*s=='-'){
    s++;
    sig=-1;
  }
  while(*s)
  {
    if(*s>='0'&&*s<='9')
    {
      ret*=10;
      ret+=*s-'0';
    }
    else return ret*sig;
    s++;
  }
  return ret*sig;
}
int str_ahextoi(const char *s)
{
  int ret=0;
  while(*s)
  {
    if(*s>='0'&&*s<='9')
    {
      ret*=16;
      ret+=*s-'0';
    }
    else if(*s>='a'&&*s<='f')
    {
      ret*=16;
      ret+=*s-'a'+10;
    }
    else if(*s>='A'&&*s<='F')
    {
      ret*=16;
      ret+=*s-'A'+10;
    }
    else return ret;
    s++;
  }
  return ret;
}
int str_atoi(const char *s)
{
  if(s[0]=='0'&&((s[1]=='x')||(s[1]=='X'))){
    return str_ahextoi(&s[2]);
  }else{
    return str_ainttoi(s);
  }
}



/*
*
* 把字符串以字符c分割为列表
*
*/
list_def *str_split(const char *s,char c)
{
  int len=str_len(s)+1;
  char *t=malloc(len);
  char *ptr1,*ptr2;
  list_def *l=list_creat_str();
  str_memcpy(t,s,len);
  ptr1=t;
  ptr2=t;
  while(*ptr1)
  {
    if(*ptr1==c){
      *ptr1=0;
      list_append_str(l,ptr2);
      ptr2=ptr1+1;
    }
    ptr1++;
  }
  list_append_str(l,ptr2);
  free(t);
  return list_temp(l);
}





/*
*
* 把字符串转化为数字列表，每个数字之间分隔符是c
*
*/
list_def *str_atod_list(const char *s, char c)
{
  list_def *sl=str_split(s,c);
  list_def *dl=list_creat_int();
  for(int i=0;i<list_length(sl);i++)
  {
    int n;
    char *d=list_get_str(sl,i);
    n=str_atoi(d);
    list_append_int(dl,n);
  }
  return tappend(dl,0);
}



/*
*
* 计算整数乘方
*
*/
float str_exp(int a,int b)
{
  int n=1;
  for(int i=0;i<b;i++){
    n*=a;
  }
  return n;
}



/*
*
* 把带一个小数点的数字字符串转化为浮点数
*
*/
float str_atof(const char *s)
{
  list_def *nums=str_split(s,'.');
  int a,b,len;
  char *sa,*sb;
  float exp;
  len=list_length(nums);
  if(len==2){
    sa=list_get_str(nums,0);
    sb=list_get_str(nums,1);
    a=str_atoi(sa);
    b=str_atoi(sb);
    if(a<0) b=-b;
    return a+(b/str_exp(10,str_len(sb)));
  }else if(len==1){
    sa=list_get_str(nums,0);
    a=str_atoi(sa);
    return a;
  }else{
    return 0;
  }
}




/*
*
* 判断字符是否是空白字符,是返回1,不是返回0
*
*/
static inline int str_is_empty_char(char c)
{
  const char table[]="\t\n\v\f\r ";
  if(str_find_char_right(table,c)!=0)
    return 1;
  else
    return 0;
}





/*
*
* 判断字符串是否是可打印,是返回1,不是返回0
*
*/
int str_is_print_str(const char *str,int len)
{
  if(len==0){
    return 0;
  }
  for(int i=0;i<len;i++)
  {
    // 既不是空白字符也不是可打印字符
    if(!(str_is_empty_char(str[i])||(str[i]>=' '&&str[i]<='~')))
      return 0;
  }
  return 1;
}





/*
*
* 去除字符串中多余的空白字符 '\t', '\n', '\v', '\f', '\r', and ' ',返回临时指针
*
*/
char *str_simplified(const char *str)
{
  int is_empty=0;
  array_def *arr=arr_creat();
  param_check(arr);
  while(str_is_empty_char(*str)){
    str++;
  }
  while(*str){
    if(str_is_empty_char(*str)==0){
      if(is_empty==1){
        arr_append(arr,' ');
        is_empty=0;
      }
      arr_append(arr,*str);
    }else{
      is_empty=1;
    }
    str++;
  }
  char *ret=tmalloc(arr_length(arr)+1);
  param_check(ret);
  memcpy(ret,arr_data(arr),arr_length(arr));
  ret[arr_length(arr)]=0;
  arr_delete(arr);
  return ret;
}





/*
*
* 给字符串指针设置值
*
*/
void _str_set(char **p,const char *str)
{
  param_check(p);
  int len=0;
  if(str)
    len=str_len(str);
  else
    len=0;
  if(*p!=0)
  {
    free(*p);
  }
  *p=malloc(len+1);
  str_cpystr(*p,str,len);
  (*p)[len]=0;
}



/*
*
* 创建一个字符串副本
*
*/
char *str_duplicate(char *p)
{
  int len=str_len(p);
  char *s=malloc(len+1);
  param_check(s);
  str_cpystr(s,p,len+1);
  return s;
}



