/*->c.bits */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>


#include "h.swis"
#include "h.kernel"
#include "h.bbc"
#include "h.os"


#include "h.bits"


int cstrncmp(char * first,char * second,int n)
{
 int f;
 int s;

 while(n--)
 {
  f=toupper(*first++);
  s=toupper(*second++);
  if(f!=s || !f) return(f-s);
 }

 return(0);
}


int cstrcmp(char * first,char * second)
{
 return(cstrncmp(first,second,-1));
}



int xcstrncmp(char * first,char * second,int n)
{
 int f;
 int s;

 while(n--)
 {
  f=toupper(*first++);
  s=toupper(*second++);
  if(f<32 && s<32) return(0);
  if(f!=s) return(f-s);
 }

 return(0);
}




void fx(int a,int x,int y)
{
 os_regset rx;

 rx.r[0]=a;
 rx.r[1]=x;
 rx.r[2]=y;

 os_swix(OS_Byte,&rx);
}



/* searches for nearest match in a sorted list                          */
/* pointer is to entry which key should be inserted before              */
/* if key should be added to end of list, pointer is to end of list + 1 */


void *bnearest(const void *key,void *base,size_t nmemb,size_t size,
                                  int (*compar)(const void *, const void *))
{
 void * lo;
 void * hi;
 void * p;
 int    ii;
 int    loi;
 int    hii;
 int    cmp;

 ii=0;
 loi=0;
 hii=nmemb-1;

 if(!nmemb) return(base);

 lo=base;
 p=lo;                                       /* compiler/play safe */
 cmp=0;
 hi=(void*)(((char*)lo)+(nmemb-1)*size);

 while(hi>=lo)
 {
  p=(char*)((((unsigned int)lo)>>1) & 0x7FFFFFFF);
  p=(((char*)p)+((((unsigned int)hi)>>1) & 0x7FFFFFFF));
  if((((unsigned int)lo) & 0x1) && (((unsigned int)hi) & 0x1))
                                                      p=(((char*)p)+1);

  ii=loi+hii;
  if(ii & 1) p=(void*)(((char*)p)-size/2);
  ii=ii>>1;

  cmp=compar(p,key);

  if(!cmp) return(p);
  else
  if(cmp<0)
  {
   lo=(void*)((char*)p+size);
   loi=ii+1;
  }
  else
  {
   hi=(void*)((char*)p-size);
   hii=ii-1;
  }
 }

 if(cmp<0) p=(void*)((char*)p+size);

 return(p);
}



int ospresent(int os)
{
 os_regset rx;

 rx.r[0]=129;
 rx.r[1]=0;
 rx.r[2]=0xFF;

 os_swix(OS_Byte,&rx);

 return(rx.r[1]-os);
}



int osversion(void)
{
 os_regset  rx;
 static int osver=0;

 if(!osver)
 {
  rx.r[0]=129;
  rx.r[1]=0;
  rx.r[2]=0xFF;

  os_swix(OS_Byte,&rx);

  osver=rx.r[1];
 }

 return(osver);
}


char * memstring(int size)
{
 static char string[16];
 int K=size/1024;
 int M=K/1024;

 if(!M && !K) sprintf(string,"%d",size);
 else
 if(!M && K) sprintf(string,"%dK",K);
 else
 {
  K-=M*1024;
  K=(K*100)/1024;
  if(K) sprintf(string,"%d.%02dM",M,K);
  else  sprintf(string,"%dM",M);
 }
 return(string);
}



char * unquotec(char * input,char * output)
{
 char * r;
 char * w;

 r=input;
 w=output;

 while(*r)
 {
  if(*r=='\"' || *r=='\\') *w++='\\';
  *w++=*r++;
 }

 *w=0;

 return(output);
}



char * quotec(char * input,char * output)
{
 char * r;
 char * w;
 int    escape;
 int    c;

 r=input;
 w=output;
 escape=0;


 while((c=*r)!=0)
 {
  if(c=='\\') escape=1;
  else
  {
   if(escape)
   {
    switch(c)
    {
     case 't':
              c='\t';
              break;
     case 'n':
              c='\n';
              break;
     case 'r':
              c='\r';
              break;
     case 'v':
              c='\v';
              break;
     case 'f':
              c='\f';
              break;
    }
    escape=0;
   }
   *w++=c;
  }
  r++;
 }

 *w=0;

 return(output);
}





 /*
  * copies the string pointed to by s2 (including the terminating nul
  * character) into the array pointed to by s1. If copying takes place
  * between objects that overlap, the behaviour is undefined.
  * Returns: the value of s1.
  */


char * xstrcpy(char *s1, const char *s2)
{
 while((*s1++=*s2++)>=32);
 *(s1-1)=0;
 return(s1);
}


void xstripstr(char * p,int len)
{
 while(*p>=32 && len>0) {p++;len--;}
 *p=0;
}


void xstripstr32(char * p)
{
 char * q;

 q=NULL;
 while(*p>=32)
 {
  if(*p==32 && !q) q=p;
  else             q=NULL;
  p++;
 }
 if(q) *q=0;
}


char * xstrncpy(char *s1,char *s2,int n)
{

 while(n-->0)
   if((*s1++=*s2++)<32) break;
 *(s1-1)=0;

 return(s1);
}



int xstrlen(char *s)
{
 char * p;
 p=s;
 while(*s++>=32);
 return(s-p-1);
}


/*

static void xmemcpy(char * d,char * s,int n)
{
 while(n-->0) *d++=*s++;
}

*/





/* expands <x$y> form path */

os_error * expandpath(char * path,char * buff,int buffsize)
{
 os_error * err;
 os_regset  rx;

 err=NULL;

 rx.r[0]=(int)path;
 rx.r[1]=(int)buff;
 rx.r[2]=buffsize;

 err=os_swix(OS_GSTrans,&rx);
 if(err) buff[0]=0;
 else    buff[rx.r[2]]=0;

 return(err);
}


