/////////////////////////////////////////////////////////////////////////////////
 
// Copyright(c) 2001-2002 Hybus Co,.ltd. All rights reserved.
 
//
 
// Module name:
 
//      lstring.c
 
//
 
// Description:
 
//
 
//
 
// Author:
 
//      bedguy
 
//
 
// Created:
 
//      2002.10
 
//
 
///////////////////////////////////////////////////////////////////////////////
 
 
 
 
 
#include "stdarg.h"
 
#include "lstring.h"
 
 
 
static void PrintChar(char *fmt, char c);
 
static void PrintDec(char *fmt, int value);
 
static void PrintHex(char *fmt, uint value);
 
static void PrintString(char *fmt, char *cptr);
 
static int Power(int num, int cnt);
 
 
 
 
 
void MemCpy32(void *dest, void *src, int numWords){
 
        volatile long *s1=dest, *s2=src;
 
        while(numWords--) {
 
                *s1++ = *s2++;
 
        }
 
        return;
 
}       // MemCpy32.
 
 
 
 
 
void MemCpy(void *dest, void *src, int cnt){
 
        char *s1=dest, *s2=src, *endptr=(char *)dest+cnt;
 
        
 
        while (s1<endptr)
 
                *s1++ = *s2++;
 
        return;
 
}       // MemCpy.
 
 
 
 
 
void MemSet(void *dest, char c, int len){
 
        char *s=dest;
 
        char *limit = (char *)dest+len;
 
 
 
        while (s < limit) *s++ = c;
 
}       // MemSet.
 
 
 
 
 
int MemCmp(void *addr1, void *addr2, int len){
 
        volatile char *s1=addr1, *s2=addr2;
 
        volatile char *endptr = (char*)addr1+len;
 
 
 
        while ((ulong)s1 < (ulong)endptr){
 
                if (*s1++ != *s2++) return *(--s1) - *(--s2);
 
        }
 
        return 0;
 
}       // MemCmp.
 
 
 
 
 
void StrCpy(char *dest, char *src){
 
        volatile char *s1=dest, *s2=src;
 
        
 
        while (*s2!=0) *s1++ = *s2++;
 
        *s1 = 0;
 
        return;
 
}       // StrCpy.
 
 
 
 
 
int StrLen(char *dest){
 
        volatile char *tmp = dest;
 
 
 
        if (!tmp) return -1;
 
        while (*tmp!=0) tmp++;
 
        return (tmp - dest);
 
}       // StrLen.
 
 
 
 
 
int StrNCmp(char *s1, char *s2, int len){
 
        int i;
 
 
 
        for(i = 0; i < len; i++){
 
                if(s1[i] != s2[i])      return ((int)s1[i]) - ((int)s2[i]);
 
                if(s1[i] == 0)          return 0;
 
        }
 
        return 0;
 
} // StrNCmp.
 
 
 
 
 
int StrCmp(char *s1, char *s2){
 
        for (; *s1 && *s2; s1++, s2++){
 
                if (*s1 != *s2) return ((int)(*s1) - (int)(*s2));
 
        }
 
        if (*s1 || *s2) return ((int)(*s1) - (int)(*s2));
 
        return 0;
 
}       // StrCmp.
 
 
 
 
 
bool HexToInt(char *s, void *retval, VAR_TYPE type){
 
        char    c;
 
        int             i;
 
        long    rval;
 
 
 
        if (!s || !retval) return false;
 
        if (!StrNCmp(s, "0x", 2)) s+=2;
 
        // fine int value.
 
        for (i=0, rval=0; i<type/4; i++){
 
                if (*s=='\0'){
 
                        if (i==0) return false;
 
                        else      break;
 
                }
 
                c = *s++;
 
 
 
                if      (c>='0' && c<='9') c-='0';
 
                else if (c>='a' && c<='f') c=c-'a'+10;
 
                else if (c>='A' && c<='F') c=c-'A'+10;
 
                else    return false;
 
 
 
                rval = rval<<4 | c;
 
        }
 
        // make retval.
 
        switch (type){
 
                case 8 :
 
                        *(char *)retval = (char)rval;
 
                        break;
 
                case 16 :
 
                        *(short *)retval = (short)rval;
 
                        break;
 
                case 32 :
 
                        *(long *)retval = (long)rval;
 
                        break;
 
                default :
 
                        return false;
 
        }
 
        return true;
 
}       // HexToInt.
 
 
 
 
 
bool DecToLong(char *s, long *retval){
 
        long remainder;
 
        if (!s || !s[0]) return false;
 
 
 
        for (*retval=0; *s; s++){
 
                if (*s < '0' || *s > '9') return false;
 
                remainder = *s - '0';
 
                *retval = *retval * 10 + remainder;
 
        }
 
 
 
        return true;
 
}       // DecToLong.
 
 
 
 
 
void HexDump(char *addr, int len){
 
        char    *s=addr, *endPtr=(char *)((long)addr+len);
 
        int             i, remainder=len%16;
 
        
 
        printf("Offset      Hex Value                                        Ascii value\n");  
        
 
        // print out 16 byte blocks.
 
        while (s+16<=endPtr){
 
                // offset ├т╖┬.
 
                printf("0x%08lx  ", (long)(s
-addr
));  
                // 16 bytes ┤▄└з╖╬ │╗┐ы ├т╖┬.
 
                for (i=0; i<16; i++){
 
                }
 
                for (i=0; i<16; i++){
 
                        if              (s
[i
]>=32 && s
[i
]<=125) printf("%c", s
[i
]);  
                }
 
                s += 16;
 
        }
 
        
 
        // Print out remainder.
 
        if (remainder){
 
                // offset ├т╖┬.
 
                printf("0x%08lx  ", (long)(s
-addr
));  
                // 16 bytes ┤▄└з╖╬ ├т╖┬╟╧░э │▓└║ ░═ ├т╖┬.
 
                for (i=0; i<remainder; i++){
 
                }
 
                for (i=0; i<(16-remainder); i++){
 
                }
 
                for (i=0; i<remainder; i++){
 
                        if              (s
[i
]>=32 && s
[i
]<=125) printf("%c", s
[i
]);  
                }
 
                for (i=0; i<(16-remainder); i++){
 
                }
 
        }
 
        return;
 
}       // HexDump.
 
 
 
 
 
//void printf(char *fmt, ...){
 
//
 
//      int             i;
 
//      va_list args;
 
//      char    *s=fmt;
 
//      char    format[10];             // fmt└╟ └╬└┌░б "%08lx"╢є╕щ, "08l"╕ж └╙╜├╖╬ ▒т╖╧.
 
//      
 
//      va_start(args, fmt);
 
//      while (*s){
 
//              if (*s=='%'){
 
//                      s++;
 
//                      // s┐б╝н "%08lx"╟№╜─└╗ ░б┴о┐═ format┐б ▒т╖╧. │к┴▀┐б ├т╖┬╟╘╝Ў┐б │╤░▄┴▄.
 
//                      format[0] = '%';
 
//                      for (i=1; i<10;){
 
//                              if (*s=='c' || *s=='d' || *s=='x' || *s=='s' || *s=='%'){
 
//                                      format[i++] = *s;
 
//                                      format[i] = '\0';
 
//                                      break;
 
//                              }
 
//                              else {
 
//                                      format[i++] = *s++;
 
//                              }
 
//                      }
 
//                      // "%s", "%c", "%d", "%x"╕ж ├г╛╞ ├т╖┬╟╥ ╟╘╝Ў ╚г├т.
 
//                      switch (*s++){
 
//                              case 'c' :
 
//                                      PrintChar(format, va_arg(args, int));
 
//                                      break;
 
//                              case 'd' :
 
//                                      PrintDec(format, va_arg(args, int));
 
//                                      break;
 
//                              case 'x' :
 
//                                      PrintHex(format, va_arg(args, int));
 
//                                      break;
 
//                              case 's' :
 
//                                      PrintString(format, va_arg(args, char *));
 
//                                      break;
 
//                              case '%' :
 
//                                      PrintChar("%c", '%');
 
//                                      break;
 
//                      }
 
//              }
 
//              else {
 
//                      PrintChar("%c", *s);
 
//                      s++;
 
//              }
 
//      }
 
//      va_end(args);
 
//      return;
 
///*
 
//      va_list args;
 
//      static char printf_buf[512];
 
//      int i;
 
//
 
//      va_start(args, fmt);
 
//      i = vsnprintf(printf_buf, sizeof(printf_buf), fmt, args);
 
//      va_end(args);
 
//      PrintString("%s",printf_buf);
 
//      //return i;
 
//      return ;
 
//*/    
 
//}
 
 
 
 
 
void PrintChar(char *fmt, char c){
 
        SerialOutputByte(c);
 
        return;
 
}
 
 
 
 
 
void PrintDec(char *fmt, int l){
 
        int             i, j;
 
        char    c, *s=fmt, tol[10];
 
        bool    flag0=false, flagl=false;       // "%08lx"┐б╝н '0', 'l'└╟ ┴╕└ч ┐й║╬.
 
        long    flagcnt=0;                                      // "%08lx"┐б╝н "8"└╗ ├г╛╞╝н long╟№└╕╖╬.
 
        bool    leading_zero=true;                      // long╟№└╟ data╕ж ├т╖┬╟╧▒т └з╟╤ ║п╝Ў.
 
        long    divisor, result, remainder;
 
 
 
        // fmt└╟ "%08lx"┐б╝н '0', '8', 'l'└╗ ╟╪╝о.
 
        for (i=0; (c=s[i]); i++){
 
                if (c=='d') break;
 
                else if (c>='1' && c<='9'){
 
                        for (j=0; s[i]>='0' && s[i]<='9'; j++){
 
                                tol[j] = s[i++];
 
                        }
 
                        tol[j] = '\0';
 
                        i--;
 
                        DecToLong(tol, &flagcnt);
 
                }
 
                else if (c=='0') flag0=true;
 
                else if (c=='l') flagl=true;
 
                else continue;
 
        }
 
 
 
        // └з└╟ flag┐б ╡√╢є ├т╖┬.
 
        if (flagcnt){
 
                if (flagcnt>9) flagcnt=9;
 
                remainder = l%(Power(10, flagcnt));     // flagcnt║╕┤┘ └н└┌╕о└╟ ╝Ў┤┬ ░╔╖п│┐. 199┐б flagcnt==2└╠╕щ, 99╕╕.
 
 
 
                for (divisor=Power(10, flagcnt-1); divisor>0; divisor/=10){
 
                        result = remainder/divisor;
 
                        remainder %= divisor;
 
 
 
                        if (result!=0 || divisor==1) leading_zero = false;
 
 
 
                        if (leading_zero==true){
 
                                if (flag0)      SerialOutputByte('0');
 
                                else            SerialOutputByte(' ');
 
                        }
 
                        else SerialOutputByte((char)(result)+'0');
 
                }
 
        } else {
 
                remainder = l;
 
 
 
                for (divisor=1000000000; divisor>0; divisor/=10){
 
                        result = remainder/divisor;
 
                        remainder %= divisor;
 
 
 
                        if (result!=0 || divisor==1) leading_zero = false;
 
                        if (leading_zero==false) SerialOutputByte((char)(result)+'0');
 
                }
 
        }
 
        return;
 
}
 
 
 
 
 
void PrintHex(char *fmt, uint l){
 
        int             i, j;
 
        char    c, tol[10];
 
        uchar *s=(uchar*)fmt;
 
        bool    flag0=false, flagr=false, flagl=false;  // flags.
 
        long    flagcnt=0;
 
        bool    leading_zero=true;
 
        char    uHex, lHex;
 
        int             cnt;                                            // "%5x"└╟ ░ц┐ь 5░│╕╕ ├т╖┬╟╧╡╡╖╧ ├т╖┬╟╤ ░│╝Ў.
 
 
 
        // fmt└╟ "%08l(L)x"┐б╝н '0', '8', 'l', 'L'└╗ ╟╪╝о.
 
        for (i=0; (c=s[i]); i++){
 
                if (c=='x') break;
 
                else if (c>='1' && c<='9'){
 
                        for (j=0; s[i]>='0' && s[i]<='9'; j++){
 
                                tol[j] = s[i++];
 
                        }
 
                        tol[j] = '\0';
 
                        i--;
 
                        DecToLong(tol, &flagcnt);
 
                }
 
                else if (c=='0') flag0=true;
 
                else if (c=='r') flagr=true;  // SWAP
 
                else if (c=='l') flagl=true;  // Long Type
 
                else continue;
 
        }
 
 
 
 
 
        s = (uchar *)(&l);
 
   if(!flagr) l = SWAP32(l);               // little, big endian┐б ╡√╢є╝н.(big└╠ ├т╖┬╟╧▒т ╜м┐Ў ╝°╝н╕ж ╣┘▓▐)
 
         
 
        
 
        // └з└╟ flag┐б ╡√╢є ├т╖┬.
 
        if (flagcnt){
 
                if (flagcnt&0x01){      // flagcnt░б ╚ж╝Ў └╧╢з, upper╕ж ╣л╜├, lower╕╕ ├т╖┬.
 
                        c = s[(8-(flagcnt+1))/2]; // ╚ж╝Ў └╧╢з ▒╫ └з─б╕ж ╞ў╟╘╟╧┤┬ ░ў└╟ ░к└╗ ░б┴о ┐╔┤╧┤┘.
 
                        
 
                        // lower 4 bits╕ж ░б┴о┐═╝н ascii code╖╬.
 
                        lHex = ((c>>0)&0x0f);
 
                        if (lHex!=0) leading_zero=false;
 
                        if (lHex<10) lHex+='0';
 
                        else         lHex+='A'-10;
 
 
 
                        // lower 4 bits ├т╖┬.
 
                        if (leading_zero){
 
                                if (flag0) SerialOutputByte('0');
 
                                else       SerialOutputByte(' ');
 
                        }
 
                        else SerialOutputByte(lHex);
 
                        
 
                        flagcnt--;
 
                }
 
 
 
                // byte┤▄└з└╟ data╕ж Hex╖╬ ├т╖┬.
 
                for (cnt=0, i=(8-flagcnt)/2; i<4; i++){
 
                        c = s[i];
 
                                
 
                        // get upper 4 bits and lower 4 bits.
 
                        uHex = ((c>>4)&0x0f);
 
                        lHex = ((c>>0)&0x0f);
 
 
 
                        // upper 4 bits and lower 4 bits to '0'~'9', 'A'~'F'.
 
                        // upper 4 bits╕ж ascii code╖╬.
 
                        if (uHex!=0) leading_zero = false;
 
                        if (uHex<10) uHex+='0';
 
                        else         uHex+='A'-10;
 
 
 
                        // upper 4 bits ├т╖┬.
 
                        if (leading_zero){
 
                                if (flag0) SerialOutputByte('0');
 
                                else       SerialOutputByte(' ');
 
                        }
 
                        else SerialOutputByte(uHex);
 
                        
 
                        // lower 4 bits╕ж ascii code╖╬.
 
                        if (lHex!=0) leading_zero = false;
 
                        if (lHex<10) lHex+='0';
 
                        else         lHex+='A'-10;
 
 
 
                        // lower 4 bits ├т╖┬.
 
                        if (leading_zero){
 
                                if (flag0) SerialOutputByte('0');
 
                                else       SerialOutputByte(' ');
 
                        }
 
                        else SerialOutputByte(lHex);
 
                }
 
        }
 
        else {
 
                for (i=0; i<4; i++){
 
                        c = s[i];
 
        
 
                        // get upper 4 bits and lower 4 bits.
 
                        uHex = ((c>>4)&0x0f);
 
                        lHex = ((c>>0)&0x0f);
 
 
 
                        // upper 4 bits and lower 4 bits to '0'~'9', 'A'~'F'.
 
                        if (uHex!=0) leading_zero = false;
 
                        if (uHex<10) uHex+='0';
 
                        else         uHex+='A'-10;
 
                        if (!leading_zero) SerialOutputByte(uHex);
 
                        
 
                        if (lHex!=0 || i==3) leading_zero = false;
 
                        if (lHex<10) lHex+='0';
 
                        else         lHex+='A'-10;
 
                        if (!leading_zero) SerialOutputByte(lHex);
 
                }
 
        }
 
        return;
 
}
 
 
 
 
 
void PrintString(char *fmt, char *s){
 
        if (!fmt || !s) return;
 
        while (*s) SerialOutputByte(*s++);
 
        return;
 
}
 
 
 
 
 
int Power(int num, int cnt){
 
        long retval=num;
 
        cnt--;
 
 
 
        while (cnt--){
 
                retval *= num;
 
        }
 
        return retval;
 
}