187 lines
2.7 KiB
C
187 lines
2.7 KiB
C
#include<stdio.h>
|
|
#include<stdbool.h>
|
|
#include<unistd.h>
|
|
#include<stdint.h>
|
|
|
|
#define __rbp(x) asm("movq %%rbp,%0":"=m"(x))
|
|
#define __rdi(x) asm("movq %%rdi,%0":"=m"(x))
|
|
#define __rsi(x) asm("movq %%rsi,%0":"=m"(x))
|
|
#define __rdx(x) asm("movq %%rdx,%0":"=m"(x))
|
|
#define __rcx(x) asm("movq %%rcx,%0":"=m"(x))
|
|
#define __r8(x) asm("movq %%r8,%0":"=m"(x))
|
|
#define __r9(x) asm("movq %%r9,%0":"=m"(x))
|
|
|
|
static int sprinti(char*s,int d);
|
|
static int sprinti16(char*s,int d);
|
|
typedef union sprint_type {int64_t i64;int32_t i32;char c;char*s;}sprint_type;
|
|
|
|
// Print formatted string with variable number
|
|
// of arguments into destination string dest
|
|
int sprint(char*dest,char*fmt,...)
|
|
{
|
|
bool special=false;
|
|
int bpos=0;
|
|
int curarg=2;
|
|
sprint_type args[6];
|
|
sprint_type rdi,rsi,rdx,rcx,r8,r9;
|
|
|
|
__rdi(rdi);
|
|
__rsi(rsi);
|
|
__rdx(rdx);
|
|
__rcx(rcx);
|
|
__r8(r8);
|
|
__r9(r9);
|
|
|
|
args[0]=rdi;
|
|
args[1]=rsi;
|
|
args[2]=rdx;
|
|
args[3]=rcx;
|
|
args[4]=r8;
|
|
args[5]=r9;
|
|
|
|
for(int i=0;fmt[i];++i)
|
|
{
|
|
switch(fmt[i])
|
|
{
|
|
|
|
case '%':
|
|
if(special)
|
|
{
|
|
dest[bpos++]=fmt[i];
|
|
special=false;
|
|
}
|
|
else
|
|
special=true;
|
|
break;
|
|
|
|
default:
|
|
if(special)
|
|
{
|
|
|
|
switch(fmt[i])
|
|
{
|
|
|
|
case 'd':
|
|
case 'i':
|
|
case 'u':
|
|
{
|
|
char tmp[1024];
|
|
int n;
|
|
n=sprinti(tmp,args[curarg++].i32);
|
|
for(int k=0;tmp[k]&&k<=n;++k)
|
|
dest[bpos++]=tmp[k];
|
|
}
|
|
break;
|
|
|
|
case 'x':
|
|
case 'p':
|
|
{
|
|
char tmp[1024];
|
|
int n;
|
|
n=sprinti16(tmp,args[curarg++].i32);
|
|
for(int k=0;tmp[k]&&k<=n;++k)
|
|
dest[bpos++]=tmp[k];
|
|
}
|
|
break;
|
|
|
|
case 's':
|
|
{
|
|
for(int k=0;args[curarg].s[k];++k)
|
|
dest[bpos++]=args[curarg].s[k];
|
|
++curarg;
|
|
}
|
|
break;
|
|
|
|
case 'c':
|
|
dest[bpos++]=args[curarg++].c;
|
|
break;
|
|
|
|
}
|
|
|
|
special=false;
|
|
}
|
|
else
|
|
dest[bpos++]=fmt[i];
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
dest[bpos]=0;
|
|
return bpos;
|
|
}
|
|
|
|
static int sprinti16(char*s,int d)
|
|
{
|
|
static char g[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
|
|
char b[32]={0};
|
|
int bp=0;
|
|
int i=0;
|
|
|
|
if(!s)return 0;
|
|
|
|
if(d<0)
|
|
{
|
|
b[bp++]='-';
|
|
d=-d;
|
|
}
|
|
|
|
// Get each digit as character
|
|
while(d>0)
|
|
{
|
|
int m=d%16;
|
|
d/=16;
|
|
b[i++]=g[m];
|
|
}
|
|
b[i]=0;
|
|
|
|
int max=i-1;
|
|
|
|
// Print reversed string
|
|
for(;i>=0;--i)
|
|
{
|
|
if(b[i]>31)
|
|
s[max-i]=b[i];
|
|
}
|
|
s[max+1]=0;
|
|
|
|
return max;
|
|
}
|
|
|
|
static int sprinti(char*s,int d)
|
|
{
|
|
char b[32]={0};
|
|
int bp=0;
|
|
int i=0;
|
|
|
|
if(!s)return 0;
|
|
|
|
if(d<0)
|
|
{
|
|
b[bp++]='-';
|
|
d=-d;
|
|
}
|
|
|
|
// Get each digit as character
|
|
while(d>0)
|
|
{
|
|
int m=d%10;
|
|
d/=10;
|
|
if(m+'0'>31)
|
|
b[i++]=m+'0';
|
|
}
|
|
b[i]=0;
|
|
|
|
int max=i-1;
|
|
|
|
// Print reversed string
|
|
for(;i>=0;--i)
|
|
{
|
|
if(b[i]>31)
|
|
s[max-i]=b[i];
|
|
}
|
|
s[max+1]=0;
|
|
|
|
return max;
|
|
}
|