/* LIBPAWNC.C * * A "glue file" for building the Pawn compiler as a DLL or shared library. * * Copyright (c) ITB CompuPhase, 2000-2006 * * 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 * the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 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 * a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. * * Version: $Id: libsc.c 3114 2005-03-17 14:48:29Z thiadmer $ */ #include #include #include #include #include #include "sc.h" #include "memfile.h" /* pc_printf() * Called for general purpose "console" output. This function prints general * purpose messages; errors go through pc_error(). The function is modelled * after printf(). */ int pc_printf(const char *message,...) { int ret; va_list argptr; va_start(argptr,message); ret=vprintf(message,argptr); va_end(argptr); return ret; } /* pc_error() * Called for producing error output. * number the error number (as documented in the manual) * message a string describing the error with embedded %d and %s tokens * filename the name of the file currently being parsed * firstline the line number at which the expression started on which * the error was found, or -1 if there is no "starting line" * lastline the line number at which the error was detected * argptr a pointer to the first of a series of arguments (for macro * "va_arg") * Return: * If the function returns 0, the parser attempts to continue compilation. * On a non-zero return value, the parser aborts. */ int pc_error(int number,char *message,char *filename,int firstline,int lastline,va_list argptr) { static char *prefix[3]={ "error", "fatal error", "warning" }; if (number!=0) { char *pre; pre=prefix[number/100]; if (firstline>=0) fprintf(stderr,"%s(%d -- %d) : %s %03d: ",filename,firstline,lastline,pre,number); else fprintf(stderr,"%s(%d) : %s %03d: ",filename,lastline,pre,number); } /* if */ vfprintf(stderr,message,argptr); fflush(stderr); return 0; } /* pc_opensrc() * Opens a source file (or include file) for reading. The "file" does not have * to be a physical file, one might compile from memory. * filename the name of the "file" to read from * Return: * 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 * function must return NULL. * Note: * Several "source files" may be open at the same time. Specifically, one * file can be open for reading and another for writing. */ void *pc_opensrc(char *filename) { return fopen(filename,"rt"); } /* pc_createsrc() * Creates/overwrites a source file for writing. The "file" does not have * to be a physical file, one might compile from memory. * filename the name of the "file" to create * Return: * 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 * function must return NULL. * Note: * Several "source files" may be open at the same time. Specifically, one * file can be open for reading and another for writing. */ void *pc_createsrc(char *filename) { return fopen(filename,"wt"); } /* pc_closesrc() * Closes a source file (or include file). The "handle" parameter has the * value that pc_opensrc() returned in an earlier call. */ void pc_closesrc(void *handle) { assert(handle!=NULL); fclose((FILE*)handle); } /* pc_resetsrc() * "position" may only hold a pointer that was previously obtained from * pc_getpossrc() */ void pc_resetsrc(void *handle,void *position) { assert(handle!=NULL); fsetpos((FILE*)handle,(fpos_t *)position); } /* pc_readsrc() * Reads a single line from the source file (or up to a maximum number of * characters if the line in the input file is too long). */ char *pc_readsrc(void *handle,unsigned char *target,int maxchars) { return fgets((char*)target,maxchars,(FILE*)handle); } /* pc_writesrc() * Writes to to the source file. There is no automatic line ending; to end a * line, write a "\n". */ int pc_writesrc(void *handle,unsigned char *source) { return fputs((char*)source,(FILE*)handle) >= 0; } void *pc_getpossrc(void *handle) { static fpos_t lastpos; /* may need to have a LIFO stack of such positions */ fgetpos((FILE*)handle,&lastpos); return &lastpos; } int pc_eofsrc(void *handle) { return feof((FILE*)handle); } /* should return a pointer, which is used as a "magic cookie" to all I/O * functions; return NULL for failure */ void *pc_openasm(char *filename) { #if defined __MSDOS__ || defined SC_LIGHT return fopen(filename,"w+t"); #else return mfcreate(filename); #endif } void pc_closeasm(void *handle, int deletefile) { #if defined __MSDOS__ || defined SC_LIGHT if (handle!=NULL) fclose((FILE*)handle); if (deletefile) remove(outfname); #else if (handle!=NULL) { if (!deletefile) mfdump((MEMFILE*)handle); mfclose((MEMFILE*)handle); } /* if */ #endif } void pc_resetasm(void *handle) { assert(handle!=NULL); #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) { #if defined __MSDOS__ || defined SC_LIGHT return fputs(string,(FILE*)handle) >= 0; #else return mfputs((MEMFILE*)handle,string); #endif } char *pc_readasm(void *handle, char *string, int maxchars) { #if defined __MSDOS__ || defined SC_LIGHT return fgets(string,maxchars,(FILE*)handle); #else return mfgets((MEMFILE*)handle,string,maxchars); #endif } extern memfile_t *bin_file; /* Should return a pointer, which is used as a "magic cookie" to all I/O * functions; return NULL for failure. */ void *pc_openbin(char *filename) { return memfile_creat(filename, 1); } void pc_closebin(void *handle,int deletefile) { if (deletefile) { memfile_destroy((memfile_t *)handle); bin_file = NULL; } else { bin_file = (memfile_t *)handle; } } /* pc_resetbin() * Can seek to any location in the file. * The offset is always from the start of the file. */ void pc_resetbin(void *handle,long offset) { memfile_seek((memfile_t *)handle, offset); } int pc_writebin(void *handle,void *buffer,int size) { return memfile_write((memfile_t *)handle, buffer, size); } long pc_lengthbin(void *handle) { return memfile_tell((memfile_t *)handle); }