Formatting options in printf
This commit is contained in:
parent
fd1626bf16
commit
07f797e577
344
include/stdio.c
344
include/stdio.c
|
@ -72,93 +72,325 @@ char * gets(char * str)
|
|||
return str;
|
||||
}
|
||||
|
||||
void printf(const char * fmt, ...)
|
||||
typedef void * (* putstrfn)(void * handle, const char * str);
|
||||
|
||||
void * putstrio(void * handle, const char * str)
|
||||
{
|
||||
puts(str);
|
||||
return handle;
|
||||
}
|
||||
|
||||
void * putstrstr(void * handle, const char * str)
|
||||
{
|
||||
char * d = (char *)handle;
|
||||
const char * s = str;
|
||||
|
||||
do {} while (*d++ = *s++);
|
||||
|
||||
return d - 1;
|
||||
}
|
||||
|
||||
struct sinfo
|
||||
{
|
||||
char fill;
|
||||
int width, precision;
|
||||
unsigned base;
|
||||
bool sign, left, prefix;
|
||||
};
|
||||
|
||||
void nformi(const sinfo * si, char * str, int v, bool s)
|
||||
{
|
||||
char buffer[10];
|
||||
|
||||
unsigned int u = v;
|
||||
bool neg = false;
|
||||
|
||||
if (s && v < 0)
|
||||
{
|
||||
neg = true;
|
||||
u = -v;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
while (u > 0)
|
||||
{
|
||||
int c = u % si->base;
|
||||
if (c >= 10)
|
||||
c += 'A' - 10;
|
||||
else
|
||||
c += '0';
|
||||
buffer[i++] = c;
|
||||
u /= si->base;
|
||||
}
|
||||
|
||||
int digits = si->precision >= 0 ? si->precision : 1;
|
||||
|
||||
while (i < digits)
|
||||
buffer[i++] = '0';
|
||||
|
||||
if (si->prefix && si->base == 16)
|
||||
{
|
||||
buffer[i++] = 'X';
|
||||
buffer[i++] = '0';
|
||||
}
|
||||
|
||||
if (neg)
|
||||
buffer[i++] = '-';
|
||||
else if (si->sign)
|
||||
buffer[i++] = '+';
|
||||
|
||||
while (i < si->width)
|
||||
buffer[i++] = si->fill;
|
||||
|
||||
while (i > 0)
|
||||
*str++ = buffer[--i];
|
||||
*str++ = 0;
|
||||
}
|
||||
|
||||
void nformf(const sinfo * si, char * str, float f, char type)
|
||||
{
|
||||
int d = 0;
|
||||
|
||||
if (f < 0.0)
|
||||
{
|
||||
f = -f;
|
||||
str[d++] = '-';
|
||||
}
|
||||
else if (si->sign)
|
||||
str[d++] = '+';
|
||||
|
||||
int exp = 0;
|
||||
|
||||
int fdigits = si->precision >= 0 ? si->precision : 6;
|
||||
|
||||
if (f != 0.0)
|
||||
{
|
||||
while (f >= 1000.0)
|
||||
{
|
||||
f /= 1000;
|
||||
exp += 3;
|
||||
}
|
||||
|
||||
while (f < 1.0)
|
||||
{
|
||||
f *= 1000;
|
||||
exp -= 3;
|
||||
}
|
||||
|
||||
while (f >= 10.0)
|
||||
{
|
||||
f /= 10;
|
||||
exp ++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int digits = fdigits + 1;
|
||||
bool fexp = type == 'e';
|
||||
|
||||
if (type == 'g')
|
||||
{
|
||||
if (exp > 3 || exp < 0)
|
||||
fexp = true;
|
||||
}
|
||||
|
||||
if (!fexp)
|
||||
{
|
||||
while (exp < 0)
|
||||
{
|
||||
f /= 10.0;
|
||||
exp++;
|
||||
}
|
||||
digits = fdigits + exp + 1;
|
||||
|
||||
float s = 0.5;
|
||||
for(int i=1; i<digits; i++)
|
||||
s /= 10.0;
|
||||
f += s;
|
||||
if (f >= 10.0)
|
||||
{
|
||||
f /= 10.0;
|
||||
fdigits--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float s = 0.5;
|
||||
for(int i=0; i<fdigits; i++)
|
||||
s /= 10.0;
|
||||
f += s;
|
||||
if (f >= 10.0)
|
||||
{
|
||||
f /= 10.0;
|
||||
exp ++;
|
||||
}
|
||||
}
|
||||
|
||||
int pdigits = digits - fdigits;
|
||||
|
||||
if (digits > 20)
|
||||
digits = 20;
|
||||
|
||||
if (pdigits == 0)
|
||||
str[d++] = '0';
|
||||
|
||||
for(int i=0; i<digits; i++)
|
||||
{
|
||||
if (i == pdigits)
|
||||
str[d++] = '.';
|
||||
int c = (int)f;
|
||||
f -= (float)c;
|
||||
f *= 10.0;
|
||||
str[d++] = c + '0';
|
||||
}
|
||||
|
||||
if (fexp)
|
||||
{
|
||||
str[d++] = 'E';
|
||||
if (exp < 0)
|
||||
{
|
||||
str[d++] = '-';
|
||||
exp = -exp;
|
||||
}
|
||||
else
|
||||
str[d++] = '+';
|
||||
|
||||
str[d++] = exp / 10 + '0';
|
||||
str[d++] = exp % 10 + '0';
|
||||
}
|
||||
|
||||
str[d++] = 0;
|
||||
if (d < si->width)
|
||||
{
|
||||
for(int i=0; i<=d; i++)
|
||||
str[si->width - i] = str[d - i];
|
||||
for(int i=0; i<si->width-d; i++)
|
||||
str[i] = ' '
|
||||
}
|
||||
}
|
||||
|
||||
void sformat(void * data, putstrfn fn, const char * fmt, int * fps)
|
||||
{
|
||||
const char * p = fmt;
|
||||
char c, buff[14];
|
||||
int * fps = (int *)&fmt + 1;
|
||||
char c, buff[21];
|
||||
int bi = 0;
|
||||
sinfo si;
|
||||
|
||||
while (c = *p++)
|
||||
{
|
||||
if (c == '%')
|
||||
{
|
||||
if (bi)
|
||||
{
|
||||
buff[bi] = 0;
|
||||
data = fn(data, buff);
|
||||
bi = 0;
|
||||
}
|
||||
c = *p++;
|
||||
|
||||
si.base = 10;
|
||||
si.width = 1;
|
||||
si.precision = -1;
|
||||
si.fill = ' ';
|
||||
si.sign = false;
|
||||
si.left = false;
|
||||
si.prefix = false;
|
||||
|
||||
while(true)
|
||||
{
|
||||
if (c == '+')
|
||||
si.sign = true;
|
||||
else if (c == '0')
|
||||
si.fill = '0';
|
||||
else if (c == '#')
|
||||
si.prefix = true;
|
||||
else
|
||||
break;
|
||||
c = *p++;
|
||||
}
|
||||
|
||||
if (c >= '0' && c <='9')
|
||||
{
|
||||
int i = 0;
|
||||
while (c >= '0' && c <='9')
|
||||
{
|
||||
i = i * 10 + c - '0';
|
||||
c = *p++;
|
||||
}
|
||||
si.width = i;
|
||||
}
|
||||
|
||||
if (c == '.')
|
||||
{
|
||||
int i = 0;
|
||||
c = *p++;
|
||||
while (c >= '0' && c <='9')
|
||||
{
|
||||
i = i * 10 + c - '0';
|
||||
c = *p++;
|
||||
}
|
||||
si.precision = i;
|
||||
}
|
||||
|
||||
if (c == 'd')
|
||||
{
|
||||
itoa(*fps++, buff, 10);
|
||||
puts(buff);
|
||||
nformi(&si, buff, *fps++, true);
|
||||
data = fn(data, buff);
|
||||
}
|
||||
else if (c == 'u')
|
||||
{
|
||||
nformi(&si, buff, *fps++, false);
|
||||
data = fn(data, buff);
|
||||
}
|
||||
else if (c == 'x')
|
||||
{
|
||||
utoa(*fps++, buff, 16);
|
||||
puts(buff);
|
||||
si.base = 16;
|
||||
nformi(&si, buff, *fps++, false);
|
||||
data = fn(data, buff);
|
||||
}
|
||||
else if (c == 'f')
|
||||
else if (c == 'f' || c == 'g' || c == 'e')
|
||||
{
|
||||
ftoa(*(float *)fps, buff);
|
||||
puts(buff);
|
||||
nformf(&si, buff, *(float *)fps, c);
|
||||
data = fn(data, buff);
|
||||
fps ++;
|
||||
fps ++;
|
||||
}
|
||||
else if (c == 's')
|
||||
{
|
||||
puts((char *)*fps++);
|
||||
data = fn(data, (char *)*fps++);
|
||||
}
|
||||
else if (c)
|
||||
{
|
||||
putchar(c);
|
||||
buff[bi++] = c;
|
||||
}
|
||||
}
|
||||
else
|
||||
putchar(c);
|
||||
{
|
||||
buff[bi++] = c;
|
||||
if (bi == 10)
|
||||
{
|
||||
buff[bi] = 0;
|
||||
data = fn(data, buff);
|
||||
bi = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bi)
|
||||
{
|
||||
buff[bi] = 0;
|
||||
data = fn(data, buff);
|
||||
bi = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void printf(const char * fmt, ...)
|
||||
{
|
||||
sformat(nullptr, putstrio, fmt, (int *)&fmt + 1);
|
||||
}
|
||||
|
||||
int sprintf(char * str, const char * fmt, ...)
|
||||
{
|
||||
const char * p = fmt, * d = str;
|
||||
char c;
|
||||
int * fps = (int *)&fmt + 1;
|
||||
|
||||
while (c = *p++)
|
||||
{
|
||||
if (c == '%')
|
||||
{
|
||||
c = *p++;
|
||||
if (c == 'd')
|
||||
{
|
||||
itoa(*fps++, d, 10);
|
||||
while (*d)
|
||||
d++;
|
||||
}
|
||||
else if (c == 'x')
|
||||
{
|
||||
utoa(*fps++, d, 16);
|
||||
while (*d)
|
||||
d++;
|
||||
}
|
||||
else if (c == 'f')
|
||||
{
|
||||
ftoa(*(float *)fps, d);
|
||||
fps += 2;
|
||||
while (*d)
|
||||
d++;
|
||||
}
|
||||
else if (c == 's')
|
||||
{
|
||||
char * s = (char *)*fps++;
|
||||
while (c = *s++)
|
||||
*d++ = c;
|
||||
}
|
||||
else if (c)
|
||||
{
|
||||
*d++ = c;
|
||||
}
|
||||
}
|
||||
else
|
||||
*d++ = c;
|
||||
}
|
||||
*d = 0;
|
||||
char * d = (char *)(sformat(str, putstrstr, fmt, (int *)&fmt + 1));
|
||||
return d - str;
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ void Emulator::DumpCycles(void)
|
|||
}
|
||||
|
||||
printf("Total Cycles %d\n", totalCycles);
|
||||
// return;
|
||||
return;
|
||||
|
||||
for (int i = 0; i < numTops; i++)
|
||||
{
|
||||
|
|
|
@ -650,16 +650,25 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
oins.mOperator = IA_MUL;
|
||||
break;
|
||||
case TK_ASSIGN_DIV:
|
||||
oins.mOperator = IA_DIVS;
|
||||
if (vll.mType->mFlags & DTF_SIGNED)
|
||||
oins.mOperator = IA_DIVS;
|
||||
else
|
||||
oins.mOperator = IA_DIVU;
|
||||
break;
|
||||
case TK_ASSIGN_MOD:
|
||||
oins.mOperator = IA_MODS;
|
||||
if (vll.mType->mFlags & DTF_SIGNED)
|
||||
oins.mOperator = IA_MODS;
|
||||
else
|
||||
oins.mOperator = IA_MODU;
|
||||
break;
|
||||
case TK_ASSIGN_SHL:
|
||||
oins.mOperator = IA_SHL;
|
||||
break;
|
||||
case TK_ASSIGN_SHR:
|
||||
oins.mOperator = IA_SHR;
|
||||
if (vll.mType->mFlags & DTF_SIGNED)
|
||||
oins.mOperator = IA_SAR;
|
||||
else
|
||||
oins.mOperator = IA_SHR;
|
||||
break;
|
||||
case TK_ASSIGN_AND:
|
||||
oins.mOperator = IA_AND;
|
||||
|
@ -1418,7 +1427,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
xins.mIntValue = atotal;
|
||||
block->Append(xins);
|
||||
|
||||
return ExValue(vl.mType->mBase, cins.mTTemp);
|
||||
return ExValue(ftype->mBase, cins.mTTemp);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -525,6 +525,13 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data)
|
|||
mType = ASMIT_NOP;
|
||||
changed = true;
|
||||
}
|
||||
else if (data.mRegs[mAddress].mImmediate)
|
||||
{
|
||||
data.mRegs[CPU_REG_A] = data.mRegs[mAddress];
|
||||
mAddress = data.mRegs[CPU_REG_A].mValue;
|
||||
mMode = ASMIM_IMMEDIATE;
|
||||
changed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
data.mRegs[CPU_REG_A].Reset();
|
||||
|
@ -547,6 +554,13 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data)
|
|||
mType = ASMIT_NOP;
|
||||
changed = true;
|
||||
}
|
||||
else if (data.mRegs[mAddress].mImmediate)
|
||||
{
|
||||
data.mRegs[CPU_REG_X] = data.mRegs[mAddress];
|
||||
mAddress = data.mRegs[CPU_REG_X].mValue;
|
||||
mMode = ASMIM_IMMEDIATE;
|
||||
changed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
data.mRegs[CPU_REG_X].Reset();
|
||||
|
@ -569,6 +583,13 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data)
|
|||
mType = ASMIT_NOP;
|
||||
changed = true;
|
||||
}
|
||||
else if (data.mRegs[mAddress].mImmediate)
|
||||
{
|
||||
data.mRegs[CPU_REG_Y] = data.mRegs[mAddress];
|
||||
mAddress = data.mRegs[CPU_REG_Y].mValue;
|
||||
mMode = ASMIM_IMMEDIATE;
|
||||
changed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
data.mRegs[CPU_REG_Y].Reset();
|
||||
|
@ -789,14 +810,17 @@ void NativeCodeInstruction::FilterRegUsage(NumberSet& requiredTemps, NumberSet&
|
|||
break;
|
||||
|
||||
case ASMIT_CMP:
|
||||
case ASMIT_STA:
|
||||
if (!providedTemps[CPU_REG_A])
|
||||
requiredTemps += CPU_REG_A;
|
||||
break;
|
||||
case ASMIT_CPX:
|
||||
case ASMIT_STX:
|
||||
if (!providedTemps[CPU_REG_X])
|
||||
requiredTemps += CPU_REG_X;
|
||||
break;
|
||||
case ASMIT_CPY:
|
||||
case ASMIT_STY:
|
||||
if (!providedTemps[CPU_REG_Y])
|
||||
requiredTemps += CPU_REG_Y;
|
||||
break;
|
||||
|
|
|
@ -40,7 +40,8 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint32 flags)
|
|||
dec->mSize = 1;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
break;
|
||||
else
|
||||
dec->mSize = 2;
|
||||
|
||||
break;
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,22,0
|
||||
PRODUCTVERSION 1,0,22,0
|
||||
FILEVERSION 1,0,23,0
|
||||
PRODUCTVERSION 1,0,23,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -43,12 +43,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "oscar64"
|
||||
VALUE "FileDescription", "oscar64 compiler"
|
||||
VALUE "FileVersion", "1.0.22.0"
|
||||
VALUE "FileVersion", "1.0.23.0"
|
||||
VALUE "InternalName", "oscar64.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2021"
|
||||
VALUE "OriginalFilename", "oscar64.exe"
|
||||
VALUE "ProductName", "oscar64"
|
||||
VALUE "ProductVersion", "1.0.22.0"
|
||||
VALUE "ProductVersion", "1.0.23.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -116,6 +116,14 @@
|
|||
"PrivateKeyFile" = "8:"
|
||||
"TimeStampServer" = "8:"
|
||||
"InstallerBootstrapper" = "3:2"
|
||||
"BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}"
|
||||
{
|
||||
"Enabled" = "11:TRUE"
|
||||
"PromptEnabled" = "11:TRUE"
|
||||
"PrerequisitesLocation" = "2:1"
|
||||
"Url" = "8:"
|
||||
"ComponentsUrl" = "8:"
|
||||
}
|
||||
}
|
||||
"Release"
|
||||
{
|
||||
|
@ -132,6 +140,14 @@
|
|||
"PrivateKeyFile" = "8:"
|
||||
"TimeStampServer" = "8:"
|
||||
"InstallerBootstrapper" = "3:2"
|
||||
"BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}"
|
||||
{
|
||||
"Enabled" = "11:TRUE"
|
||||
"PromptEnabled" = "11:TRUE"
|
||||
"PrerequisitesLocation" = "2:1"
|
||||
"Url" = "8:"
|
||||
"ComponentsUrl" = "8:"
|
||||
}
|
||||
}
|
||||
}
|
||||
"Deployable"
|
||||
|
@ -480,15 +496,15 @@
|
|||
{
|
||||
"Name" = "8:Microsoft Visual Studio"
|
||||
"ProductName" = "8:oscar64"
|
||||
"ProductCode" = "8:{8DBBA799-02D3-41CF-AC4B-48ACAD587438}"
|
||||
"PackageCode" = "8:{19B7DAD0-EB7E-49E0-99EC-3C46ADD0F434}"
|
||||
"ProductCode" = "8:{468390A3-2F63-4CA4-9043-3B1AEEA1852F}"
|
||||
"PackageCode" = "8:{A55AE2BA-C814-4AD7-BBB6-00042C360D73}"
|
||||
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
||||
"AspNetVersion" = "8:2.0.50727.0"
|
||||
"RestartWWWService" = "11:FALSE"
|
||||
"RemovePreviousVersions" = "11:TRUE"
|
||||
"DetectNewerInstalledVersion" = "11:TRUE"
|
||||
"InstallAllUsers" = "11:FALSE"
|
||||
"ProductVersion" = "8:1.0.22"
|
||||
"ProductVersion" = "8:1.0.23"
|
||||
"Manufacturer" = "8:oscar64"
|
||||
"ARPHELPTELEPHONE" = "8:"
|
||||
"ARPHELPLINK" = "8:"
|
||||
|
|
Loading…
Reference in New Issue