@@ -21,10 +21,6 @@ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those
|
||||
of the authors and should not be interpreted as representing official policies,
|
||||
either expressed or implied, of the FreeBSD Project.
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -519,6 +515,26 @@ void GenJumpIfNotZero(int label)
|
||||
MipsOpNumLabel, label);
|
||||
}
|
||||
|
||||
fpos_t GenPrologPos;
|
||||
|
||||
STATIC
|
||||
void GenWriteFrameSize(void)
|
||||
{
|
||||
unsigned size = -CurFxnMinLocalOfs;
|
||||
int pfx = size ? ' ' : '#';
|
||||
printf2("\t%csubu\t$29, $29, %10u\n", pfx, size); // 10 chars are enough for 32-bit unsigned ints
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenUpdateFrameSize(void)
|
||||
{
|
||||
fpos_t pos;
|
||||
fgetpos(OutFile, &pos);
|
||||
fsetpos(OutFile, &GenPrologPos);
|
||||
GenWriteFrameSize();
|
||||
fsetpos(OutFile, &pos);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenFxnProlog(void)
|
||||
{
|
||||
@@ -549,6 +565,9 @@ void GenFxnProlog(void)
|
||||
MipsOpRegA0 + i, 0,
|
||||
MipsOpIndRegFp, 8 + 4 * i);
|
||||
}
|
||||
|
||||
fgetpos(OutFile, &GenPrologPos);
|
||||
GenWriteFrameSize();
|
||||
}
|
||||
|
||||
STATIC
|
||||
@@ -562,15 +581,11 @@ void GenGrowStack(int size)
|
||||
MipsOpConst, size);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenFxnProlog2(void)
|
||||
{
|
||||
GenGrowStack(-CurFxnMinLocalOfs);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenFxnEpilog(void)
|
||||
{
|
||||
GenUpdateFrameSize();
|
||||
|
||||
GenPrintInstr2Operands(MipsInstrMov, 0,
|
||||
MipsOpRegSp, 0,
|
||||
MipsOpRegFp, 0);
|
||||
@@ -2225,3 +2240,4 @@ void GenFin(void)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -21,10 +21,6 @@ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those
|
||||
of the authors and should not be interpreted as representing official policies,
|
||||
either expressed or implied, of the FreeBSD Project.
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -791,6 +787,50 @@ void GenJumpIfNotZero(int label)
|
||||
X86OpNumLabel, label);
|
||||
}
|
||||
|
||||
fpos_t GenPrologPos;
|
||||
|
||||
STATIC
|
||||
void GenWriteFrameSize(void)
|
||||
{
|
||||
unsigned size = -CurFxnMinLocalOfs;
|
||||
int pfx = size ? ' ' : ';';
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
if (SizeOfWord == 4 &&
|
||||
OutputFormat != FormatSegHuge &&
|
||||
WindowsStack)
|
||||
{
|
||||
int pfx = (size >= 4096) ? ' ' : ';';
|
||||
// When targeting Windows, call equivalent of _chkstk() to
|
||||
// correctly grow the stack page by page by probing it
|
||||
if (!WinChkStkLabel)
|
||||
WinChkStkLabel = -LabelCnt++; // reserve a label for _chkstk() and mark unused
|
||||
if (WinChkStkLabel < 0 && pfx == ' ')
|
||||
WinChkStkLabel = -WinChkStkLabel; // _chkstk() has been used at least once
|
||||
|
||||
printf2("\t%cmov\teax, %10u\n", pfx, size); // 10 chars are enough for 32-bit unsigned ints
|
||||
printf2("\t%ccall\t", pfx);
|
||||
GenPrintNumLabel((WinChkStkLabel < 0) ? -WinChkStkLabel : WinChkStkLabel);
|
||||
puts2("");
|
||||
}
|
||||
#endif
|
||||
if (SizeOfWord == 2)
|
||||
printf2("\t%csub\tsp, %10u\n", pfx, size); // 10 chars are enough for 32-bit unsigned ints
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
else
|
||||
printf2("\t%csub\tesp, %10u\n", pfx, size); // 10 chars are enough for 32-bit unsigned ints
|
||||
#endif
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenUpdateFrameSize(void)
|
||||
{
|
||||
fpos_t pos;
|
||||
fgetpos(OutFile, &pos);
|
||||
fsetpos(OutFile, &GenPrologPos);
|
||||
GenWriteFrameSize();
|
||||
fsetpos(OutFile, &pos);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenFxnProlog(void)
|
||||
{
|
||||
@@ -799,6 +839,8 @@ void GenFxnProlog(void)
|
||||
GenPrintInstr2Operands(X86InstrMov, 0,
|
||||
X86OpRegBpWord, 0,
|
||||
X86OpRegSpWord, 0);
|
||||
fgetpos(OutFile, &GenPrologPos);
|
||||
GenWriteFrameSize();
|
||||
}
|
||||
|
||||
STATIC
|
||||
@@ -806,39 +848,15 @@ void GenGrowStack(int size)
|
||||
{
|
||||
if (!size)
|
||||
return;
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
if (SizeOfWord == 4 &&
|
||||
OutputFormat != FormatSegHuge &&
|
||||
WindowsStack &&
|
||||
size >= 4096)
|
||||
{
|
||||
// When targeting Windows, call equivalent of _chkstk() to
|
||||
// correctly grow the stack page by page by probing it
|
||||
if (!WinChkStkLabel)
|
||||
WinChkStkLabel = LabelCnt++;
|
||||
|
||||
GenPrintInstr2Operands(X86InstrMov, 0,
|
||||
X86OpRegAWord, 0,
|
||||
X86OpConst, size);
|
||||
printf2("\tcall\t");
|
||||
GenPrintNumLabel(WinChkStkLabel); // TBD??? use dedicated instr/op fxn???
|
||||
puts2("");
|
||||
}
|
||||
#endif
|
||||
GenPrintInstr2Operands(X86InstrSub, 0,
|
||||
X86OpRegSpWord, 0,
|
||||
X86OpConst, size);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenFxnProlog2(void)
|
||||
{
|
||||
GenGrowStack(-CurFxnMinLocalOfs);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenFxnEpilog(void)
|
||||
{
|
||||
GenUpdateFrameSize();
|
||||
GenPrintInstrNoOperand(X86InstrLeave);
|
||||
GenPrintInstrNoOperand(X86InstrRet);
|
||||
}
|
||||
@@ -899,10 +917,13 @@ void GenIsrProlog(void)
|
||||
|
||||
puts2("\tpush\tebp\n"
|
||||
"\tmov\tebp, esp");
|
||||
fgetpos(OutFile, &GenPrologPos);
|
||||
GenWriteFrameSize();
|
||||
}
|
||||
|
||||
void GenIsrEpilog(void)
|
||||
{
|
||||
GenUpdateFrameSize();
|
||||
puts2("\tdb\t0x66\n\tleave");
|
||||
|
||||
puts2("\tpop\teax"); // fake return address
|
||||
@@ -3171,6 +3192,7 @@ void GenFin(void)
|
||||
puts2(CodeHeaderFooter[0]);
|
||||
|
||||
GenNumLabel(StructCpyLabel);
|
||||
CurFxnMinLocalOfs = 0;
|
||||
GenFxnProlog();
|
||||
|
||||
if (SizeOfWord == 2)
|
||||
@@ -3248,6 +3270,7 @@ void GenFin(void)
|
||||
puts2(CodeHeaderFooter[0]);
|
||||
|
||||
GenNumLabel(StructPushLabel);
|
||||
CurFxnMinLocalOfs = 0;
|
||||
GenFxnProlog();
|
||||
|
||||
if (SizeOfWord == 2)
|
||||
@@ -3336,7 +3359,7 @@ void GenFin(void)
|
||||
#endif
|
||||
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
if (WinChkStkLabel)
|
||||
if (WinChkStkLabel > 0) // if _chkstk() has been used at least once
|
||||
{
|
||||
// When targeting Windows, simulate _chkstk() to
|
||||
// correctly grow the stack page by page by probing it
|
||||
@@ -3378,3 +3401,4 @@ void GenFin(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2013-2014, Alexey Frunze
|
||||
Copyright (c) 2013-2015, Alexey Frunze
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -21,10 +21,6 @@ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those
|
||||
of the authors and should not be interpreted as representing official policies,
|
||||
either expressed or implied, of the FreeBSD Project.
|
||||
*/
|
||||
|
||||
#ifndef __APPLE__
|
||||
@@ -749,6 +745,22 @@ int WriteFile(unsigned Handle,
|
||||
"push dword [ebp+8]\n"
|
||||
"call [__imp__WriteFile]");
|
||||
}
|
||||
|
||||
extern unsigned (*_imp__SetFilePointer)(unsigned Handle,
|
||||
int lDistanceToMove,
|
||||
int* lpDistanceToMoveHigh,
|
||||
unsigned dwMoveMethod);
|
||||
unsigned SetFilePointer(unsigned Handle,
|
||||
int lDistanceToMove,
|
||||
int* lpDistanceToMoveHigh,
|
||||
unsigned dwMoveMethod)
|
||||
{
|
||||
asm("push dword [ebp+20]\n"
|
||||
"push dword [ebp+16]\n"
|
||||
"push dword [ebp+12]\n"
|
||||
"push dword [ebp+8]\n"
|
||||
"call [__imp__SetFilePointer]");
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
#ifdef _RETROBSD
|
||||
@@ -786,7 +798,7 @@ int OsCreateOrTruncate(char* name)
|
||||
#ifdef _LINUX
|
||||
asm("mov eax, 5\n" // sys_open
|
||||
"mov ebx, [ebp + 8]\n"
|
||||
"mov ecx, 0x641\n" // truncate if exists, else create, writing only
|
||||
"mov ecx, 0x241\n" // truncate if exists, else create, writing only
|
||||
"mov edx, 664o\n" // rw-rw-r--
|
||||
"int 0x80\n"
|
||||
"mov ebx, eax\n"
|
||||
@@ -1055,6 +1067,67 @@ int OsWrite(int fd, void* p, unsigned s)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef __SMALLER_C_16__
|
||||
long OsLseek(int fd, long ofs, int whence)
|
||||
{
|
||||
#ifdef _RETROBSD
|
||||
long pos;
|
||||
asm volatile ("move $4, %1\n"
|
||||
"move $5, %2\n"
|
||||
"move $6, %3\n"
|
||||
"syscall 19\n" // SYS_lseek
|
||||
"nop\n"
|
||||
"nop\n"
|
||||
"move %0, $2\n"
|
||||
: "=r" (pos)
|
||||
: "r" (fd), "r" (ofs), "r" (whence)
|
||||
: "$2", "$4", "$5", "$6");
|
||||
return pos;
|
||||
#else
|
||||
#ifdef _LINUX
|
||||
asm("mov eax, 19\n" // sys_lseek
|
||||
"mov ebx, [ebp + 8]\n"
|
||||
"mov ecx, [ebp + 12]\n"
|
||||
"mov edx, [ebp + 16]\n"
|
||||
"int 0x80");
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
return SetFilePointer(fd, ofs, 0, whence);
|
||||
#else
|
||||
asm("mov ah, 0x42\n"
|
||||
"mov bx, [bp + 8]\n"
|
||||
"mov dx, [bp + 12]\n"
|
||||
"mov cx, [bp + 12 + 2]\n"
|
||||
"mov al, [bp + 16]\n"
|
||||
"int 0x21");
|
||||
asm("sbb ebx, ebx\n"
|
||||
"and eax, 0xffff\n"
|
||||
"shl edx, 16\n"
|
||||
"or eax, edx\n"
|
||||
"or eax, ebx");
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
int OsLseek16(int fd, unsigned short ofs[2], int whence)
|
||||
{
|
||||
asm("mov ah, 0x42\n"
|
||||
"mov bx, [bp + 4]\n"
|
||||
"mov si, [bp + 6]");
|
||||
asm("mov dx, [si]\n"
|
||||
"mov cx, [si + 2]\n"
|
||||
"mov al, [bp + 8]\n"
|
||||
"int 0x21");
|
||||
asm("sbb bx, bx\n"
|
||||
"or ax, bx\n"
|
||||
"or dx, bx\n"
|
||||
"mov [si], ax\n"
|
||||
"mov [si + 2], dx\n"
|
||||
"mov ax, bx");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _DOS
|
||||
unsigned DosGetPspSeg(void)
|
||||
{
|
||||
@@ -1398,4 +1471,81 @@ int fclose(FILE* stream)
|
||||
--__FileCnt__;
|
||||
return OsClose(fd);
|
||||
}
|
||||
|
||||
struct fpos_t_
|
||||
{
|
||||
union
|
||||
{
|
||||
unsigned short halves[2]; // for 16-bit memory models without 32-bit longs
|
||||
int align; // for alignment on machine word boundary
|
||||
} u;
|
||||
}; // keep in sync with stdio.h !!!
|
||||
#define fpos_t struct fpos_t_
|
||||
|
||||
// Note, these fgetpos() and fsetpos() are implemented for write-only files
|
||||
|
||||
int fgetpos(FILE* stream, fpos_t* pos)
|
||||
{
|
||||
unsigned i = (unsigned)stream, fd;
|
||||
|
||||
fd = __FileHandles__[--i];
|
||||
|
||||
#ifndef __SMALLER_C_16__
|
||||
{
|
||||
long p;
|
||||
if ((p = OsLseek(fd, 0, 1/*SEEK_CUR*/)) < 0)
|
||||
return -1;
|
||||
|
||||
p += __FileBufPos__[i];
|
||||
pos->u.align = p;
|
||||
}
|
||||
#else
|
||||
{
|
||||
unsigned short p[2];
|
||||
p[0] = p[1] = 0;
|
||||
if (OsLseek16(fd, p, 1/*SEEK_CUR*/) < 0)
|
||||
return -1;
|
||||
p[1] += __FileBufPos__[i] > 0xFFFF - p[0];
|
||||
p[0] += __FileBufPos__[i];
|
||||
pos->u.halves[0] = p[0];
|
||||
pos->u.halves[1] = p[1];
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fsetpos(FILE* stream, fpos_t* pos)
|
||||
{
|
||||
unsigned i = (unsigned)stream, fd;
|
||||
unsigned sz;
|
||||
|
||||
fd = __FileHandles__[--i];
|
||||
|
||||
// flush
|
||||
sz = __FileBufPos__[i];
|
||||
if (sz)
|
||||
{
|
||||
if ((unsigned)OsWrite(fd, __FileBufs__[i], sz) != sz)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// seek
|
||||
#ifndef __SMALLER_C_16__
|
||||
{
|
||||
long p = pos->u.align;
|
||||
if ((p = OsLseek(fd, p, 0/*SEEK_SET*/)) < 0)
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
{
|
||||
if (OsLseek16(fd, pos->u.halves, 0/*SEEK_SET*/) < 0)
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
__FileBufDirty__[i] = 0;
|
||||
__FileBufSize__[i] = __FileBufPos__[i] = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /*__APPLE__*/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2012, Alexey Frunze
|
||||
Copyright (c) 2012-2015, Alexey Frunze
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -21,6 +21,3 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those
|
||||
of the authors and should not be interpreted as representing official policies,
|
||||
either expressed or implied, of the FreeBSD Project.
|
||||
|
||||
@@ -7,14 +7,39 @@ that can then be assembled and linked into DOS, Windows and Linux programs.
|
||||
|
||||
Code generation for MIPS CPUs is also supported (primarily for RetroBSD).
|
||||
|
||||
The compiler is capable of compiling its own source code.
|
||||
Code generation for the TR3200 CPU and VASM is supported (see Trillek).
|
||||
|
||||
You can fully recompile the compiler only with itself and NASM for the
|
||||
x86 platform (no linker is necessary).
|
||||
The compiler is capable of compiling itself.
|
||||
|
||||
The core compiler comes with a linker and a compiler driver (the driver
|
||||
invokes the core compiler, the assembler, and the linker and supports
|
||||
options similar to those of gcc).
|
||||
|
||||
There's no decent preprocessor in Smaller C as of now, but the compiler
|
||||
driver can invoke gcc (or gcc.exe) for preprocessing if instructed.
|
||||
|
||||
The standard C library is work-in-progress and it's close to completion.
|
||||
|
||||
See the Wiki for more up-to-date details:
|
||||
http://github.com/alexfru/SmallerC/wiki
|
||||
|
||||
For the lack of a better place, you can discuss Smaller C here:
|
||||
https://hackaday.io/project/5569-smaller-c
|
||||
|
||||
Links:
|
||||
NASM: http://nasm.us/
|
||||
YASM: http://yasm.tortall.net/
|
||||
CWSDPMI: http://homer.rice.edu/~sandmann/cwsdpmi/
|
||||
HX DOS Extender: https://web.archive.org/web/20141003032346/http://www.japheth.de/
|
||||
RetroBSD: http://retrobsd.org/
|
||||
VASM: http://sun.hasenbraten.de/vasm/
|
||||
Trillek: http://trillek.org/
|
||||
|
||||
Normative and other useful documents on C:
|
||||
C99 + TC1 + TC2 + TC3, WG14 N1256:
|
||||
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
|
||||
Rationale for C99:
|
||||
http://www.open-std.org/jtc1/sc22/wg14/www/docs/C99RationaleV5.10.pdf
|
||||
The New C Standard: An Economic and Cultural Commentary:
|
||||
http://www.knosof.co.uk/cbook/cbook.html
|
||||
|
||||
|
||||
@@ -21,10 +21,6 @@ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those
|
||||
of the authors and should not be interpreted as representing official policies,
|
||||
either expressed or implied, of the FreeBSD Project.
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -159,6 +155,17 @@ int fprintf(FILE*, char*, ...);
|
||||
int vprintf(char*, void*);
|
||||
//int vfprintf(FILE*, char*, va_list);
|
||||
int vfprintf(FILE*, char*, void*);
|
||||
struct fpos_t_
|
||||
{
|
||||
union
|
||||
{
|
||||
unsigned short halves[2]; // for 16-bit memory models without 32-bit longs
|
||||
int align; // for alignment on machine word boundary
|
||||
} u;
|
||||
}; // keep in sync with stdio.h !!!
|
||||
#define fpos_t struct fpos_t_
|
||||
int fgetpos(FILE*, fpos_t*);
|
||||
int fsetpos(FILE*, fpos_t*);
|
||||
|
||||
#endif // #ifndef __SMALLER_C__
|
||||
|
||||
@@ -406,8 +413,6 @@ void GenJumpIfEqual(int val, int Label);
|
||||
STATIC
|
||||
void GenFxnProlog(void);
|
||||
STATIC
|
||||
void GenFxnProlog2(void);
|
||||
STATIC
|
||||
void GenFxnEpilog(void);
|
||||
void GenIsrProlog(void);
|
||||
void GenIsrEpilog(void);
|
||||
@@ -4726,31 +4731,24 @@ void DetermineVaListType(void)
|
||||
#endif // DETERMINE_VA_LIST
|
||||
#endif // __SMALLER_C__
|
||||
|
||||
// Equivalent to puts() but outputs to OutFile
|
||||
// if it's not NULL.
|
||||
// Equivalent to puts() but outputs to OutFile.
|
||||
STATIC
|
||||
int puts2(char* s)
|
||||
{
|
||||
int res;
|
||||
if (OutFile)
|
||||
if (!OutFile)
|
||||
return 0;
|
||||
// Turbo C++ 1.01's fputs() returns EOF if s is empty, which is wrong.
|
||||
// Hence the workaround.
|
||||
if (*s == '\0' || (res = fputs(s, OutFile)) >= 0)
|
||||
{
|
||||
// Turbo C++ 1.01's fputs() returns EOF if s is empty, which is wrong.
|
||||
// Hence the workaround.
|
||||
if (*s == '\0' || (res = fputs(s, OutFile)) >= 0)
|
||||
{
|
||||
// unlike puts(), fputs() doesn't append '\n', append it manually
|
||||
res = fputc('\n', OutFile);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
res = puts(s);
|
||||
// unlike puts(), fputs() doesn't append '\n', append it manually
|
||||
res = fputc('\n', OutFile);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// Equivalent to printf() but outputs to OutFile
|
||||
// if it's not NULL.
|
||||
// Equivalent to printf() but outputs to OutFile.
|
||||
STATIC
|
||||
int printf2(char* format, ...)
|
||||
{
|
||||
@@ -4763,31 +4761,24 @@ int printf2(char* format, ...)
|
||||
void* vl = &format + 1;
|
||||
#endif
|
||||
|
||||
if (!OutFile)
|
||||
return 0;
|
||||
#ifndef __SMALLER_C__
|
||||
if (OutFile)
|
||||
res = vfprintf(OutFile, format, vl);
|
||||
else
|
||||
res = vprintf(format, vl);
|
||||
res = vfprintf(OutFile, format, vl);
|
||||
#else
|
||||
// TBD!!! This is not good. Really need the va_something macros.
|
||||
#ifdef DETERMINE_VA_LIST
|
||||
if (VaListType == 2)
|
||||
{
|
||||
// va_list is a one-element array containing a pointer
|
||||
if (OutFile)
|
||||
res = vfprintf(OutFile, format, &vl);
|
||||
else
|
||||
res = vprintf(format, &vl);
|
||||
res = vfprintf(OutFile, format, &vl);
|
||||
}
|
||||
else // if (VaListType == 1)
|
||||
// fallthrough
|
||||
#endif // DETERMINE_VA_LIST
|
||||
{
|
||||
// va_list is a pointer
|
||||
if (OutFile)
|
||||
res = vfprintf(OutFile, format, vl);
|
||||
else
|
||||
res = vprintf(format, vl);
|
||||
res = vfprintf(OutFile, format, vl);
|
||||
}
|
||||
#endif // __SMALLER_C__
|
||||
|
||||
@@ -4881,7 +4872,7 @@ void warning(char* format, ...)
|
||||
|
||||
warnCnt++;
|
||||
|
||||
if (!(warnings && OutFile))
|
||||
if (!warnings)
|
||||
return;
|
||||
|
||||
printf("Warning in \"%s\" (%d:%d)\n", FileNames[fidx], LineNo, LinePos);
|
||||
@@ -6928,7 +6919,6 @@ int ParseDecl(int tok, unsigned structInfo[4], int cast, int label)
|
||||
// local variables to the symbol table and parse the body.
|
||||
int undoSymbolsPtr = SyntaxStackCnt;
|
||||
int undoIdents = IdentTableLen;
|
||||
int locAllocLabel = (LabelCnt += 2) - 2;
|
||||
int i;
|
||||
int Main;
|
||||
|
||||
@@ -6941,7 +6931,7 @@ int ParseDecl(int tok, unsigned structInfo[4], int cast, int label)
|
||||
|
||||
gotoLabCnt = 0;
|
||||
|
||||
if (verbose && OutFile)
|
||||
if (verbose)
|
||||
printf("%s()\n", CurFxnName);
|
||||
|
||||
ParseLevel++;
|
||||
@@ -6959,7 +6949,6 @@ int ParseDecl(int tok, unsigned structInfo[4], int cast, int label)
|
||||
puts2(CurHeaderFooter[0]);
|
||||
|
||||
GenLabel(CurFxnName, Static);
|
||||
CurFxnEpilogLabel = LabelCnt++;
|
||||
|
||||
#ifndef MIPS
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
@@ -6969,9 +6958,7 @@ int ParseDecl(int tok, unsigned structInfo[4], int cast, int label)
|
||||
#endif
|
||||
#endif
|
||||
GenFxnProlog();
|
||||
|
||||
GenJumpUncond(locAllocLabel + 1);
|
||||
GenNumLabel(locAllocLabel);
|
||||
CurFxnEpilogLabel = LabelCnt++;
|
||||
|
||||
AddFxnParamSymbols(lastSyntaxPtr);
|
||||
|
||||
@@ -7013,10 +7000,6 @@ int ParseDecl(int tok, unsigned structInfo[4], int cast, int label)
|
||||
#endif
|
||||
GenFxnEpilog();
|
||||
|
||||
GenNumLabel(locAllocLabel + 1);
|
||||
GenFxnProlog2();
|
||||
GenJumpUncond(locAllocLabel);
|
||||
|
||||
puts2(CurHeaderFooter[1]);
|
||||
CurHeaderFooter = NULL;
|
||||
|
||||
@@ -8223,6 +8206,8 @@ int main(int argc, char** argv)
|
||||
|
||||
if (!FileCnt)
|
||||
error("Input file not specified\n");
|
||||
if (!OutFile)
|
||||
error("Output file not specified\n");
|
||||
|
||||
GenInitFinalize();
|
||||
|
||||
@@ -8272,7 +8257,7 @@ int main(int argc, char** argv)
|
||||
|
||||
GenStartCommentLine(); printf2("Next label number: %d\n", LabelCnt);
|
||||
|
||||
if (warnings && warnCnt && OutFile)
|
||||
if (warnings && warnCnt)
|
||||
printf("%d warnings\n", warnCnt);
|
||||
GenStartCommentLine(); printf2("Compilation succeeded.\n");
|
||||
|
||||
@@ -8281,3 +8266,4 @@ int main(int argc, char** argv)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user