#include "lvprintf.h"
#include <windows.h>
extern TCHAR sDecimal[];
class lvprintf{
UINT cp;
union S{
char*a;
wchar_t*w;
S(char*x):a(x) {}
S(wchar_t*x):w(x) {}
};
S s;
int slen;
union const_S{
const char*a;
const wchar_t*w;
const_S(const char*x):a(x) {}
const_S(const wchar_t*x):w(x) {}
};
const_S fmt;
va_list va;
int dlen;
struct P{
int f,j,k;
void reset() {f=0; j=-1, k=-1;}
int&jk() {return f&0x0006 ? k:j;}
}p;
int pk; // Punkt oder Komma
void exec();
int getchar();
int peekchar(int);
void putchar(int);
char buf[34];
void putbuf() {putstr(buf);}
void putstr(const_S, bool=false,int maxch=-1);
public:
lvprintf(char*_s,int _slen,const char*_fmt,va_list _va):
cp(CP_ACP),
s(_s),
slen(_slen),
fmt(_fmt),
va(_va) {
exec();
}
lvprintf(wchar_t*_s,int _slen,const wchar_t*_fmt,va_list _va):
cp(1200),
s(_s),
slen(_slen),
fmt(_fmt),
va(_va) {
exec();
}
operator int() {return dlen;}
};
void lvprintf::exec() {
dlen=0;
pk=*sDecimal;
while (int c=getchar()) {
if (c=='%') {
p.reset();
for (int i=0;c=peekchar(i);i++) switch (c) {
case 'h': p.f|=0x0800; break;
case 'l': p.f+=0x1000; break;
case '.': p.f|=0x0002; break; // Kommastellen
case ',': p.f|=0x0004; break; // Kommastellen
case '0': p.f|=0x0008; break;
case '+': p.f|=0x0010; break;
case '-': p.f|=0x0020; break; // linksbündig
case '_': p.f|=0x0040; break; // Signifikante Stellen
case '\'': p.f|=0x0080; break;
case ' ': p.f|=0x0100; break;
case '#': p.f|=0x0200; break;
case '*': p.jk()=va_arg(va,int); break;
default: if ('1'<=c && c<='9') {
int i=p.jk();
if (i<0) i=0;
p.jk()=i*10+c-'0';
}else switch (c) {
case ';': pk=p.f&0x02?'.':p.f&0x04?',':*sDecimal; break;
case 'd': _itoa(va_arg(va,int),buf,0); putbuf(); break;
case 'x':
case 'X': _itoa(va_arg(va,unsigned),buf,16); putbuf(); break;
case 's': putstr(va_arg(va,const char*),cp==1200,p.k); break;
case 'S': putstr(va_arg(va,const char*),cp!=1200,p.k); break;
}
}
}else putchar(c);
}
putchar(0);
}
int lvprintf::getchar() {
if (cp==1200) return *fmt.w++;
return *fmt.a++;
}
int lvprintf::peekchar(int i) {
if (cp==1200) return fmt.w[i];
return fmt.a[i];
}
void lvprintf::putchar(int c) {
if (!slen) return;
if (cp==1200) *s.w++=c;
else *s.a++=c;
--slen;
dlen++;
}
void lvprintf::putstr(const_S s,bool wide,int maxch) {
int l=wide?wcslen(s.w):strlen(s.a);
if (maxch>=0 && l>maxch) l=maxch;
int padding=p.j-l; if (padding<0) padding=0;
if (!(p.f&0x0020) && padding) do putchar(p.f&0x0008?'0':' '); while(--padding);
if (l) do putchar(wide?*s.w++:*s.a++); while (--l);
if (p.f&0x0020 && padding) do putchar(p.f&0x0008?'0':' '); while(--padding);
}
DLLFUNC int _stdcall lvvsprintfW(wchar_t*s,int slen,const wchar_t*fmt,va_list va) {
return lvprintf(s,slen,fmt,va); // ruft den Konstruktor und den Cast-Operator
}
DLLFUNC int _cdecl lvsprintfW(wchar_t*s,int slen,const wchar_t*fmt,...) {
va_list va;
va_start(va,fmt);
int ret=lvprintf(s,slen,fmt,va);
va_end(va);
return ret;
}
DLLFUNC int _stdcall lvvsprintfA(char*s,int slen,const char*fmt,va_list va) {
return lvprintf(s,slen,fmt,va); // ruft den Konstruktor und den Cast-Operator
}
DLLFUNC int _cdecl lvsprintfA(char*s,int slen,const char*fmt,...) {
va_list va;
va_start(va,fmt);
int ret=lvprintf(s,slen,fmt,va);
va_end(va);
return ret;
}
Detected encoding: UTF-8 | 0
|