Port sc4 to C++.

This commit is contained in:
David Anderson 2014-08-22 00:12:16 -07:00
parent 9c005d93ed
commit 234b4907ed
4 changed files with 204 additions and 230 deletions

View File

@ -85,7 +85,7 @@ binary.sources += [
'sc1.c', 'sc1.c',
'sc2.c', 'sc2.c',
'sc3.c', 'sc3.c',
'sc4.c', 'sc4.cpp',
'sc5.cpp', 'sc5.cpp',
'sc6.cpp', 'sc6.cpp',
'sc7.cpp', 'sc7.cpp',

View File

@ -1,25 +1,25 @@
// vim: set sts=8 ts=4 sw=4 tw=99 noet: // vim: set sts=8 ts=4 sw=4 tw=99 noet:
/* LIBPAWNC.C /* LIBPAWNC.C
* *
* A "glue file" for building the Pawn compiler as a DLL or shared library. * A "glue file" for building the Pawn compiler as a DLL or shared library.
* *
* Copyright (c) ITB CompuPhase, 2000-2006 * Copyright (c) ITB CompuPhase, 2000-2006
* *
* This software is provided "as-is", without any express or implied warranty. * This software is provided "as-is", without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from * In no event will the authors be held liable for any damages arising from
* the use of this software. * the use of this software.
* *
* Permission is granted to anyone to use this software for any purpose, * Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it * including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions: * freely, subject to the following restrictions:
* *
* 1. The origin of this software must not be misrepresented; you must not * 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software in * claim that you wrote the original software. If you use this software in
* a product, an acknowledgment in the product documentation would be * a product, an acknowledgment in the product documentation would be
* appreciated but is not required. * appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be * 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software. * misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution. * 3. This notice may not be removed or altered from any source distribution.
* *
* Version: $Id$ * Version: $Id$
*/ */
@ -43,150 +43,150 @@
*/ */
int pc_printf(const char *message,...) int pc_printf(const char *message,...)
{ {
int ret; int ret;
va_list argptr; va_list argptr;
va_start(argptr,message); va_start(argptr,message);
ret=vprintf(message,argptr); ret=vprintf(message,argptr);
va_end(argptr); va_end(argptr);
return ret; return ret;
} }
/* pc_error() /* pc_error()
* Called for producing error output. * Called for producing error output.
* number the error number (as documented in the manual) * number the error number (as documented in the manual)
* message a string describing the error with embedded %d and %s tokens * message a string describing the error with embedded %d and %s tokens
* filename the name of the file currently being parsed * filename the name of the file currently being parsed
* firstline the line number at which the expression started on which * firstline the line number at which the expression started on which
* the error was found, or -1 if there is no "starting line" * the error was found, or -1 if there is no "starting line"
* lastline the line number at which the error was detected * lastline the line number at which the error was detected
* argptr a pointer to the first of a series of arguments (for macro * argptr a pointer to the first of a series of arguments (for macro
* "va_arg") * "va_arg")
* Return: * Return:
* If the function returns 0, the parser attempts to continue compilation. * If the function returns 0, the parser attempts to continue compilation.
* On a non-zero return value, the parser aborts. * On a non-zero return value, the parser aborts.
*/ */
int pc_error(int number,const char *message,const char *filename,int firstline,int lastline,va_list argptr) int pc_error(int number,const char *message,const char *filename,int firstline,int lastline,va_list argptr)
{ {
static const char *prefix[3]={ "error", "fatal error", "warning" }; static const char *prefix[3]={ "error", "fatal error", "warning" };
if (number!=0) { if (number!=0) {
int idx; int idx;
if (number < 160) if (number < 160)
idx = 0; idx = 0;
else if (number < 200) else if (number < 200)
idx = 1; idx = 1;
else else
idx = 2; idx = 2;
const char *pre=prefix[idx]; const char *pre=prefix[idx];
if (firstline>=0) if (firstline>=0)
fprintf(stdout,"%s(%d -- %d) : %s %03d: ",filename,firstline,lastline,pre,number); fprintf(stdout,"%s(%d -- %d) : %s %03d: ",filename,firstline,lastline,pre,number);
else else
fprintf(stdout,"%s(%d) : %s %03d: ",filename,lastline,pre,number); fprintf(stdout,"%s(%d) : %s %03d: ",filename,lastline,pre,number);
} /* if */ } /* if */
vfprintf(stdout,message,argptr); vfprintf(stdout,message,argptr);
fflush(stdout); fflush(stdout);
return 0; return 0;
} }
typedef struct src_file_s { typedef struct src_file_s {
FILE *fp; // Set if writing. FILE *fp; // Set if writing.
char *buffer; // IO buffer. char *buffer; // IO buffer.
char *pos; // IO position. char *pos; // IO position.
char *end; // End of buffer. char *end; // End of buffer.
size_t maxlength; // Maximum length of the writable buffer. size_t maxlength; // Maximum length of the writable buffer.
} src_file_t; } src_file_t;
/* pc_opensrc() /* pc_opensrc()
* Opens a source file (or include file) for reading. The "file" does not have * Opens a source file (or include file) for reading. The "file" does not have
* to be a physical file, one might compile from memory. * to be a physical file, one might compile from memory.
* filename the name of the "file" to read from * filename the name of the "file" to read from
* Return: * Return:
* The function must return a pointer, which is used as a "magic cookie" to * The function must return a pointer, which is used as a "magic cookie" to
* all I/O functions. When failing to open the file for reading, the * all I/O functions. When failing to open the file for reading, the
* function must return NULL. * function must return NULL.
* Note: * Note:
* Several "source files" may be open at the same time. Specifically, one * Several "source files" may be open at the same time. Specifically, one
* file can be open for reading and another for writing. * file can be open for reading and another for writing.
*/ */
void *pc_opensrc(char *filename) void *pc_opensrc(char *filename)
{ {
FILE *fp = NULL; FILE *fp = NULL;
long length; long length;
src_file_t *src = NULL; src_file_t *src = NULL;
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__ || defined DARWIN #if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__ || defined DARWIN
struct stat fileInfo; struct stat fileInfo;
if (stat(filename, &fileInfo) != 0) { if (stat(filename, &fileInfo) != 0) {
return NULL; return NULL;
} }
if (S_ISDIR(fileInfo.st_mode)) { if (S_ISDIR(fileInfo.st_mode)) {
return NULL; return NULL;
} }
#endif #endif
if ((fp = fopen(filename, "rb")) == NULL) if ((fp = fopen(filename, "rb")) == NULL)
return NULL; return NULL;
if (fseek(fp, 0, SEEK_END) == -1) if (fseek(fp, 0, SEEK_END) == -1)
goto err; goto err;
if ((length = ftell(fp)) == -1) if ((length = ftell(fp)) == -1)
goto err; goto err;
if (fseek(fp, 0, SEEK_SET) == -1) if (fseek(fp, 0, SEEK_SET) == -1)
goto err; goto err;
if ((src = (src_file_t *)calloc(1, sizeof(src_file_t))) == NULL) if ((src = (src_file_t *)calloc(1, sizeof(src_file_t))) == NULL)
goto err; goto err;
if ((src->buffer = (char *)calloc(length, sizeof(char))) == NULL) if ((src->buffer = (char *)calloc(length, sizeof(char))) == NULL)
goto err; goto err;
if (fread(src->buffer, length, 1, fp) != 1) if (fread(src->buffer, length, 1, fp) != 1)
goto err; goto err;
src->pos = src->buffer; src->pos = src->buffer;
src->end = src->buffer + length; src->end = src->buffer + length;
fclose(fp); fclose(fp);
return src; return src;
err: err:
pc_closesrc(src); pc_closesrc(src);
fclose(fp); fclose(fp);
return NULL; return NULL;
} }
/* pc_createsrc() /* pc_createsrc()
* Creates/overwrites a source file for writing. The "file" does not have * Creates/overwrites a source file for writing. The "file" does not have
* to be a physical file, one might compile from memory. * to be a physical file, one might compile from memory.
* filename the name of the "file" to create * filename the name of the "file" to create
* Return: * Return:
* The function must return a pointer which is used as a "magic cookie" to * The function must return a pointer which is used as a "magic cookie" to
* all I/O functions. When failing to open the file for reading, the * all I/O functions. When failing to open the file for reading, the
* function must return NULL. * function must return NULL.
* Note: * Note:
* Several "source files" may be open at the same time. Specifically, one * Several "source files" may be open at the same time. Specifically, one
* file can be open for reading and another for writing. * file can be open for reading and another for writing.
*/ */
void *pc_createsrc(char *filename) void *pc_createsrc(char *filename)
{ {
src_file_t *src = (src_file_t *)calloc(1, sizeof(src_file_t)); src_file_t *src = (src_file_t *)calloc(1, sizeof(src_file_t));
if (!src) if (!src)
return NULL; return NULL;
if ((src->fp = fopen(filename, "wt")) == NULL) { if ((src->fp = fopen(filename, "wt")) == NULL) {
pc_closesrc(src); pc_closesrc(src);
return NULL; return NULL;
} }
src->maxlength = 1024; src->maxlength = 1024;
if ((src->buffer = (char *)calloc(1, src->maxlength)) == NULL) { if ((src->buffer = (char *)calloc(1, src->maxlength)) == NULL) {
pc_closesrc(src); pc_closesrc(src);
return NULL; return NULL;
} }
src->pos = src->buffer; src->pos = src->buffer;
src->end = src->buffer + src->maxlength; src->end = src->buffer + src->maxlength;
return src; return src;
} }
/* pc_closesrc() /* pc_closesrc()
@ -195,15 +195,15 @@ void *pc_createsrc(char *filename)
*/ */
void pc_closesrc(void *handle) void pc_closesrc(void *handle)
{ {
src_file_t *src = (src_file_t *)handle; src_file_t *src = (src_file_t *)handle;
if (!src) if (!src)
return; return;
if (src->fp) { if (src->fp) {
fwrite(src->buffer, src->pos - src->buffer, 1, src->fp); fwrite(src->buffer, src->pos - src->buffer, 1, src->fp);
fclose(src->fp); fclose(src->fp);
} }
free(src->buffer); free(src->buffer);
free(src); free(src);
} }
/* pc_readsrc() /* pc_readsrc()
@ -212,35 +212,35 @@ void pc_closesrc(void *handle)
*/ */
char *pc_readsrc(void *handle,unsigned char *target,int maxchars) char *pc_readsrc(void *handle,unsigned char *target,int maxchars)
{ {
src_file_t *src = (src_file_t *)handle; src_file_t *src = (src_file_t *)handle;
char *outptr = (char *)target; char *outptr = (char *)target;
char *outend = outptr + maxchars; char *outend = outptr + maxchars;
assert(!src->fp); assert(!src->fp);
if (src->pos == src->end) if (src->pos == src->end)
return NULL; return NULL;
while (outptr < outend && src->pos < src->end) { while (outptr < outend && src->pos < src->end) {
char c = *src->pos++; char c = *src->pos++;
*outptr++ = c; *outptr++ = c;
if (c == '\n') if (c == '\n')
break; break;
if (c == '\r') { if (c == '\r') {
// Handle CRLF. // Handle CRLF.
if (src->pos < src->end && *src->pos == '\n') { if (src->pos < src->end && *src->pos == '\n') {
src->pos++; src->pos++;
if (outptr < outend) if (outptr < outend)
*outptr++ = '\n'; *outptr++ = '\n';
} }
break; break;
} }
} }
// Caller passes in a buffer of size >= maxchars+1. // Caller passes in a buffer of size >= maxchars+1.
*outptr = '\0'; *outptr = '\0';
return (char *)target; return (char *)target;
} }
/* pc_writesrc() /* pc_writesrc()
@ -249,43 +249,43 @@ char *pc_readsrc(void *handle,unsigned char *target,int maxchars)
*/ */
int pc_writesrc(void *handle,unsigned char *source) int pc_writesrc(void *handle,unsigned char *source)
{ {
char *str = (char *)source; char *str = (char *)source;
size_t len = strlen(str); size_t len = strlen(str);
src_file_t *src = (src_file_t *)handle; src_file_t *src = (src_file_t *)handle;
assert(src->fp && src->maxlength); assert(src->fp && src->maxlength);
if (src->pos + len > src->end) { if (src->pos + len > src->end) {
char *newbuf; char *newbuf;
size_t newmax = src->maxlength; size_t newmax = src->maxlength;
size_t newlen = (src->pos - src->buffer) + len; size_t newlen = (src->pos - src->buffer) + len;
while (newmax < newlen) { while (newmax < newlen) {
// Grow by 1.5X // Grow by 1.5X
newmax += newmax + newmax / 2; newmax += newmax + newmax / 2;
if (newmax < src->maxlength) if (newmax < src->maxlength)
abort(); abort();
} }
newbuf = (char *)realloc(src->buffer, newmax); newbuf = (char *)realloc(src->buffer, newmax);
if (!newbuf) if (!newbuf)
abort(); abort();
src->pos = newbuf + (src->pos - src->buffer); src->pos = newbuf + (src->pos - src->buffer);
src->end = newbuf + newmax; src->end = newbuf + newmax;
src->buffer = newbuf; src->buffer = newbuf;
src->maxlength = newmax; src->maxlength = newmax;
} }
strcpy(src->pos, str); strcpy(src->pos, str);
src->pos += len; src->pos += len;
return 0; return 0;
} }
void *pc_getpossrc(void *handle,void *position) void *pc_getpossrc(void *handle,void *position)
{ {
src_file_t *src = (src_file_t *)handle; src_file_t *src = (src_file_t *)handle;
assert(!src->fp); assert(!src->fp);
return (void *)(ptrdiff_t)(src->pos - src->buffer); return (void *)(ptrdiff_t)(src->pos - src->buffer);
} }
/* pc_resetsrc() /* pc_resetsrc()
@ -294,20 +294,20 @@ void *pc_getpossrc(void *handle,void *position)
*/ */
void pc_resetsrc(void *handle,void *position) void pc_resetsrc(void *handle,void *position)
{ {
src_file_t *src = (src_file_t *)handle; src_file_t *src = (src_file_t *)handle;
ptrdiff_t pos = (ptrdiff_t)position; ptrdiff_t pos = (ptrdiff_t)position;
assert(!src->fp); assert(!src->fp);
assert(pos >= 0 && src->buffer + pos <= src->end); assert(pos >= 0 && src->buffer + pos <= src->end);
src->pos = src->buffer + pos; src->pos = src->buffer + pos;
} }
int pc_eofsrc(void *handle) int pc_eofsrc(void *handle)
{ {
src_file_t *src = (src_file_t *)handle; src_file_t *src = (src_file_t *)handle;
assert(!src->fp); assert(!src->fp);
return src->pos == src->end; return src->pos == src->end;
} }
/* should return a pointer, which is used as a "magic cookie" to all I/O /* should return a pointer, which is used as a "magic cookie" to all I/O
@ -315,56 +315,31 @@ int pc_eofsrc(void *handle)
*/ */
void *pc_openasm(char *filename) void *pc_openasm(char *filename)
{ {
#if defined __MSDOS__ || defined SC_LIGHT return mfcreate(filename);
return fopen(filename,"w+t");
#else
return mfcreate(filename);
#endif
} }
void pc_closeasm(void *handle, int deletefile) void pc_closeasm(void *handle, int deletefile)
{ {
#if defined __MSDOS__ || defined SC_LIGHT if (handle!=NULL) {
if (handle!=NULL) if (!deletefile)
fclose((FILE*)handle); mfdump((MEMFILE*)handle);
if (deletefile) mfclose((MEMFILE*)handle);
remove(outfname); } /* if */
#else
if (handle!=NULL) {
if (!deletefile)
mfdump((MEMFILE*)handle);
mfclose((MEMFILE*)handle);
} /* if */
#endif
} }
void pc_resetasm(void *handle) void pc_resetasm(void *handle)
{ {
assert(handle!=NULL); mfseek((MEMFILE*)handle,0,SEEK_SET);
#if defined __MSDOS__ || defined SC_LIGHT
fflush((FILE*)handle);
fseek((FILE*)handle,0,SEEK_SET);
#else
mfseek((MEMFILE*)handle,0,SEEK_SET);
#endif
} }
int pc_writeasm(void *handle,char *string) int pc_writeasm(void *handle,const char *string)
{ {
#if defined __MSDOS__ || defined SC_LIGHT return mfputs((MEMFILE*)handle,string);
return fputs(string,(FILE*)handle) >= 0;
#else
return mfputs((MEMFILE*)handle,string);
#endif
} }
char *pc_readasm(void *handle, char *string, int maxchars) char *pc_readasm(void *handle, char *string, int maxchars)
{ {
#if defined __MSDOS__ || defined SC_LIGHT return mfgets((MEMFILE*)handle,string,maxchars);
return fgets(string,maxchars,(FILE*)handle);
#else
return mfgets((MEMFILE*)handle,string,maxchars);
#endif
} }
extern memfile_t *bin_file; extern memfile_t *bin_file;
@ -374,18 +349,17 @@ extern memfile_t *bin_file;
*/ */
void *pc_openbin(char *filename) void *pc_openbin(char *filename)
{ {
return memfile_creat(filename, 1); return memfile_creat(filename, 1);
} }
void pc_closebin(void *handle,int deletefile) void pc_closebin(void *handle,int deletefile)
{ {
if (deletefile) if (deletefile) {
{ memfile_destroy((memfile_t *)handle);
memfile_destroy((memfile_t *)handle); bin_file = NULL;
bin_file = NULL; } else {
} else { bin_file = (memfile_t *)handle;
bin_file = (memfile_t *)handle; }
}
} }
/* pc_resetbin() /* pc_resetbin()
@ -394,15 +368,15 @@ void pc_closebin(void *handle,int deletefile)
*/ */
void pc_resetbin(void *handle,long offset) void pc_resetbin(void *handle,long offset)
{ {
memfile_seek((memfile_t *)handle, offset); memfile_seek((memfile_t *)handle, offset);
} }
int pc_writebin(void *handle,void *buffer,int size) int pc_writebin(void *handle,void *buffer,int size)
{ {
return memfile_write((memfile_t *)handle, buffer, size); return memfile_write((memfile_t *)handle, buffer, size);
} }
long pc_lengthbin(void *handle) long pc_lengthbin(void *handle)
{ {
return memfile_tell((memfile_t *)handle); return memfile_tell((memfile_t *)handle);
} }

View File

@ -580,7 +580,7 @@ int pc_eofsrc(void *handle);
void *pc_openasm(char *filename); /* read/write */ void *pc_openasm(char *filename); /* read/write */
void pc_closeasm(void *handle,int deletefile); void pc_closeasm(void *handle,int deletefile);
void pc_resetasm(void *handle); void pc_resetasm(void *handle);
int pc_writeasm(void *handle,char *str); int pc_writeasm(void *handle,const char *str);
char *pc_readasm(void *handle,char *target,int maxchars); char *pc_readasm(void *handle,char *target,int maxchars);
/* output to binary (.AMX) file */ /* output to binary (.AMX) file */