Merge branch 'master' into fix_emit_crash

This commit is contained in:
VVWVV 2017-07-29 22:21:31 +03:00
commit 223838de79
16 changed files with 311 additions and 324 deletions

13
.editorconfig Normal file
View File

@ -0,0 +1,13 @@
# EditorConfig is awesome: http://EditorConfig.org
root = true
[*]
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.{def,rc}]
indent_size = 4

View File

@ -1,130 +0,0 @@
# - Returns a version string from Git
#
# These functions force a re-configure on each git commit so that you can
# trust the values of the variables in your build system.
#
# get_git_head_revision(<refspecvar> <hashvar> [<additional arguments to git describe> ...])
#
# Returns the refspec and sha hash of the current head revision
#
# git_describe(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe on the source tree, and adjusting
# the output so that it tests false if an error occurs.
#
# git_get_exact_tag(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe --exact-match on the source tree,
# and adjusting the output so that it tests false if there was no exact
# matching tag.
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
if(__get_git_revision_description)
return()
endif()
set(__get_git_revision_description YES)
# We must run the following at "include" time, not at function call time,
# to find the path to this module rather than the path to a calling list file
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
function(get_git_head_revision _refspecvar _hashvar)
set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories
set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}")
get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH)
if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT)
# We have reached the root directory, we are not in git
set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
return()
endif()
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
endwhile()
# check if this is a submodule
if(NOT IS_DIRECTORY ${GIT_DIR})
file(READ ${GIT_DIR} submodule)
string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule})
get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE)
endif()
set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
if(NOT EXISTS "${GIT_DATA}")
file(MAKE_DIRECTORY "${GIT_DATA}")
endif()
if(NOT EXISTS "${GIT_DIR}/HEAD")
return()
endif()
set(HEAD_FILE "${GIT_DATA}/HEAD")
configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY)
configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
"${GIT_DATA}/grabRef.cmake"
@ONLY)
include("${GIT_DATA}/grabRef.cmake")
set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE)
set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE)
endfunction()
function(git_describe _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
return()
endif()
# TODO sanitize
#if((${ARGN}" MATCHES "&&") OR
# (ARGN MATCHES "||") OR
# (ARGN MATCHES "\\;"))
# message("Please report the following error to the project!")
# message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
#endif()
#message(STATUS "Arguments to execute_process: ${ARGN}")
execute_process(COMMAND
"${GIT_EXECUTABLE}"
describe
${hash}
${ARGN}
WORKING_DIRECTORY
"${CMAKE_SOURCE_DIR}"
RESULT_VARIABLE
res
OUTPUT_VARIABLE
out
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "${out}-${res}-NOTFOUND")
endif()
set(${_var} "${out}" PARENT_SCOPE)
endfunction()
function(git_get_exact_tag _var)
git_describe(out --exact-match ${ARGN})
set(${_var} "${out}" PARENT_SCOPE)
endfunction()

View File

@ -1,38 +0,0 @@
#
# Internal file for GetGitRevisionDescription.cmake
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
set(HEAD_HASH)
file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
if(HEAD_CONTENTS MATCHES "ref")
# named branch
string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
if(EXISTS "@GIT_DIR@/${HEAD_REF}")
configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
elseif(EXISTS "@GIT_DIR@/logs/${HEAD_REF}")
configure_file("@GIT_DIR@/logs/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
set(HEAD_HASH "${HEAD_REF}")
endif()
else()
# detached HEAD
configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
endif()
if(NOT HEAD_HASH)
file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
string(STRIP "${HEAD_HASH}" HEAD_HASH)
endif()

View File

@ -24,8 +24,7 @@ Background
----------
The project was originally started as a set of patches aimed to create a compiler
that would be compatible with the compiler used in [SA-MP (San Andreas Multiplayer)]
(http://sa-mp.com/).
that would be compatible with the compiler used in [SA-MP (San Andreas Multiplayer)](http://sa-mp.com/).
SA-MP uses a modified version of Pawn 3.2.3664 [1] with Windows-only executables,
and the developers said that they lost the source code for it which means it can't

View File

@ -5,17 +5,11 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../cmake)
set(VERSION_MAJOR 3)
set(VERSION_MINOR 10)
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR})
set(VERSION_BUILD 2)
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_BUILD})
set(VERSION_STR ${VERSION})
math(EXPR VERSION_INT "${VERSION_MAJOR} << 8 | ${VERSION_MINOR}")
# Append git commit hash to the version string
include(GetGitRevisionDescription)
git_describe(GIT_COMMIT --always)
if(GIT_COMMIT)
set(VERSION_STR ${VERSION_STR}.${GIT_COMMIT})
endif()
# check for optional include files
include(CheckIncludeFile)
check_include_file("unistd.h" HAVE_UNISTD_H)
@ -34,6 +28,10 @@ check_include_file("alloca.h" HAVE_ALLOCA_H)
if(HAVE_ALLOCA_H)
add_definitions(-DHAVE_ALLOCA_H)
endif()
check_include_file("endian.h" HAVE_ENDIAN_H)
if(HAVE_ENDIAN_H)
add_definitions(-DHAVE_ENDIAN_H)
endif()
# check for optional library functions
include(CheckFunctionExists)
@ -56,7 +54,8 @@ if(UNIX)
link_libraries(pthread)
endif()
configure_file(version.h.in version.h)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/version.h.in
${CMAKE_CURRENT_BINARY_DIR}/version.h)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# The Pawn compiler shared library
@ -79,7 +78,7 @@ set(PAWNC_SRCS
scmemfil.c
scstate.c
scvars.c
${CMAKE_BINARY_DIR}/version.h)
version.h)
set_source_files_properties(sc1.c COMPILE_FLAGS -DNO_MAIN)
if(WIN32)
set(PAWNC_SRCS ${PAWNC_SRCS} libpawnc.rc)
@ -87,7 +86,7 @@ if(WIN32)
if(BORLAND)
# Borland linker uses a DEF file if one is in the output directory
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpawnc.def.borland
${CMAKE_BINARY_DIR}/pawnc.def
${CMAKE_CURRENT_BINARY_DIR}/pawnc.def
COPYONLY)
else()
# Microsoft Visual C/C++ supports a DEF file as if it were a source file
@ -106,6 +105,7 @@ if(WATCOM) #Watcom C/C++ does not support a .DEF file for the exports
elseif(MINGW)
set_target_properties(pawnc PROPERTIES LINK_FLAGS
"-Wl,--enable-stdcall-fixup")
set_target_properties(pawnc PROPERTIES PREFIX "")
endif()
# The Pawn compiler driver (console program)
@ -115,7 +115,7 @@ if(WIN32)
if(BORLAND)
# Borland linker uses a DEF file if one is in the output directory
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/pawncc.def.borland
${CMAKE_BINARY_DIR}/pawncc.def
${CMAKE_CURRENT_BINARY_DIR}/pawncc.def
COPYONLY)
else()
# Microsoft Visual C/C++ supports a DEF file as if it were a source file
@ -139,8 +139,7 @@ endif()
# Install compiler and disassembler binaries
install(TARGETS pawnc pawncc pawndisasm
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
LIBRARY DESTINATION lib)
if(MSVC)
# If building with Microsoft Visual C++ also install corresponding
# Program Database files (for debugging)

View File

@ -220,6 +220,7 @@ typedef struct s_symbol {
#define flgDEPRECATED 0x01 /* symbol is deprecated (avoid use) */
#define flagNAKED 0x10 /* function is naked */
#define flagPREDEF 0x20 /* symbol is pre-defined; successor of uPREDEF */
#define uTAGOF 0x40 /* set in the "hasdefault" field of the arginfo struct */
#define uSIZEOF 0x80 /* set in the "hasdefault" field of the arginfo struct */
@ -527,6 +528,8 @@ SC_FUNC constvalue *append_constval(constvalue *table,const char *name,cell val,
SC_FUNC constvalue *find_constval(constvalue *table,char *name,int index);
SC_FUNC void delete_consttable(constvalue *table);
SC_FUNC symbol *add_constant(char *name,cell val,int vclass,int tag);
SC_FUNC symbol *add_builtin_constant(char *name,cell val,int vclass,int tag);
SC_FUNC symbol *add_builtin_string_constant(char *name,const char *val,int vclass);
SC_FUNC void exporttag(int tag);
SC_FUNC void sc_attachdocumentation(symbol *sym);
@ -583,7 +586,9 @@ SC_FUNC void begcseg(void);
SC_FUNC void begdseg(void);
SC_FUNC void setline(int chkbounds);
SC_FUNC void setfiledirect(char *name);
SC_FUNC void setfileconst(char *name);
SC_FUNC void setlinedirect(int line);
SC_FUNC void setlineconst(int line);
SC_FUNC void setlabel(int index);
SC_FUNC void markexpr(optmark type,const char *name,cell offset);
SC_FUNC void startfunc(char *fname);

View File

@ -29,6 +29,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#if defined __WIN32__ || defined _WIN32 || defined __MSDOS__
#include <conio.h>
@ -81,6 +82,7 @@ static void setconfig(char *root);
static void setcaption(void);
static void about(void);
static void setconstants(void);
static void setstringconstants(void);
static void parse(void);
static void dumplits(void);
static void dumpzero(int count);
@ -89,7 +91,7 @@ static void declglb(char *firstname,int firsttag,int fpublic,int fstatic,
int stock,int fconst);
static int declloc(int fstatic);
static void decl_const(int table);
static void decl_enum(int table);
static void decl_enum(int table,int fstatic);
static cell needsub(int *tag,constvalue **enumroot);
static void initials(int ident,int tag,cell *size,int dim[],int numdim,
constvalue *enumroot);
@ -570,8 +572,8 @@ int pc_compile(int argc, char *argv[])
sc_needsemicolon ? "true" : "false",
sc_tabsize);
pc_writeasm(outf,string);
setfiledirect(inpfname);
} /* if */
setfiledirect(inpfname);
/* do the first pass through the file (or possibly two or more "first passes") */
sc_parsenum=0;
inpfmark=pc_getpossrc(inpf_org);
@ -596,7 +598,8 @@ int pc_compile(int argc, char *argv[])
fline=skipinput; /* reset line number */
sc_reparse=FALSE; /* assume no extra passes */
sc_status=statFIRST; /* resetglobals() resets it to IDLE */
setstringconstants();
setfileconst(inpfname);
if (strlen(incfname)>0) {
if (strcmp(incfname,sDEF_PREFIX)==0) {
plungefile(incfname,FALSE,TRUE); /* parse "default.inc" */
@ -660,7 +663,9 @@ int pc_compile(int argc, char *argv[])
fline=skipinput; /* reset line number */
lexinit(); /* clear internal flags of lex() */
sc_status=statWRITE; /* allow to write --this variable was reset by resetglobals() */
setstringconstants();
writeleader(&glbtab);
setfileconst(inpfname);
insert_dbgfile(inpfname);
if (strlen(incfname)>0) {
if (strcmp(incfname,sDEF_PREFIX)==0)
@ -1457,57 +1462,74 @@ static void setconstants(void)
append_constval(&tagname_tab,"_",0,0);/* "untagged" */
append_constval(&tagname_tab,"bool",1,0);
add_constant("true",1,sGLOBAL,1); /* boolean flags */
add_constant("false",0,sGLOBAL,1);
add_constant("EOS",0,sGLOBAL,0); /* End Of String, or '\0' */
add_builtin_constant("true",1,sGLOBAL,1); /* boolean flags */
add_builtin_constant("false",0,sGLOBAL,1);
add_builtin_constant("EOS",0,sGLOBAL,0); /* End Of String, or '\0' */
#if PAWN_CELL_SIZE==16
add_constant("cellbits",16,sGLOBAL,0);
add_builtin_constant("cellbits",16,sGLOBAL,0);
#if defined _I16_MAX
add_constant("cellmax",_I16_MAX,sGLOBAL,0);
add_constant("cellmin",_I16_MIN,sGLOBAL,0);
add_builtin_constant("cellmax",_I16_MAX,sGLOBAL,0);
add_builtin_constant("cellmin",_I16_MIN,sGLOBAL,0);
#else
add_constant("cellmax",SHRT_MAX,sGLOBAL,0);
add_constant("cellmin",SHRT_MIN,sGLOBAL,0);
add_builtin_constant("cellmax",SHRT_MAX,sGLOBAL,0);
add_builtin_constant("cellmin",SHRT_MIN,sGLOBAL,0);
#endif
#elif PAWN_CELL_SIZE==32
add_constant("cellbits",32,sGLOBAL,0);
add_builtin_constant("cellbits",32,sGLOBAL,0);
#if defined _I32_MAX
add_constant("cellmax",_I32_MAX,sGLOBAL,0);
add_constant("cellmin",_I32_MIN,sGLOBAL,0);
add_builtin_constant("cellmax",_I32_MAX,sGLOBAL,0);
add_builtin_constant("cellmin",_I32_MIN,sGLOBAL,0);
#else
add_constant("cellmax",INT_MAX,sGLOBAL,0);
add_constant("cellmin",INT_MIN,sGLOBAL,0);
add_builtin_constant("cellmax",INT_MAX,sGLOBAL,0);
add_builtin_constant("cellmin",INT_MIN,sGLOBAL,0);
#endif
#elif PAWN_CELL_SIZE==64
#if !defined _I64_MIN
#define _I64_MIN (-9223372036854775807ULL - 1)
#define _I64_MAX 9223372036854775807ULL
#endif
add_constant("cellbits",64,sGLOBAL,0);
add_constant("cellmax",_I64_MAX,sGLOBAL,0);
add_constant("cellmin",_I64_MIN,sGLOBAL,0);
add_builtin_constant("cellbits",64,sGLOBAL,0);
add_builtin_constant("cellmax",_I64_MAX,sGLOBAL,0);
add_builtin_constant("cellmin",_I64_MIN,sGLOBAL,0);
#else
#error Unsupported cell size
#endif
add_constant("charbits",sCHARBITS,sGLOBAL,0);
add_constant("charmin",0,sGLOBAL,0);
add_constant("charmax",~(-1 << sCHARBITS) - 1,sGLOBAL,0);
add_constant("ucharmax",(1 << (sizeof(cell)-1)*8)-1,sGLOBAL,0);
add_builtin_constant("charbits",sCHARBITS,sGLOBAL,0);
add_builtin_constant("charmin",0,sGLOBAL,0);
add_builtin_constant("charmax",~((ucell)-1 << sCHARBITS) - 1,sGLOBAL,0);
add_builtin_constant("ucharmax",(1 << (sizeof(cell)-1)*8)-1,sGLOBAL,0);
add_constant("__Pawn",VERSION_INT,sGLOBAL,0);
add_constant("__line",0,sGLOBAL,0);
add_constant("__compat",pc_compat,sGLOBAL,0);
add_builtin_constant("__Pawn",VERSION_INT,sGLOBAL,0);
add_builtin_constant("__PawnBuild",VERSION_BUILD,sGLOBAL,0);
add_builtin_constant("__line",0,sGLOBAL,0);
add_builtin_constant("__compat",pc_compat,sGLOBAL,0);
debug=0;
if ((sc_debug & (sCHKBOUNDS | sSYMBOLIC))==(sCHKBOUNDS | sSYMBOLIC))
debug=2;
else if ((sc_debug & sCHKBOUNDS)==sCHKBOUNDS)
debug=1;
add_constant("debug",debug,sGLOBAL,0);
add_builtin_constant("debug",debug,sGLOBAL,0);
append_constval(&sc_automaton_tab,"",0,0); /* anonymous automaton */
}
static void setstringconstants()
{
time_t now;
char timebuf[sizeof("11:22:33")];
char datebuf[sizeof("10 Jan 2017")];
assert(sc_status!=statIDLE);
add_builtin_string_constant("__file","",sGLOBAL);
now = time(NULL);
strftime(timebuf,sizeof(timebuf),"%H:%M:%S",localtime(&now));
add_builtin_string_constant("__time",timebuf,sGLOBAL);
strftime(datebuf,sizeof(datebuf),"%d %b %Y",localtime(&now));
add_builtin_string_constant("__date",datebuf,sGLOBAL);
}
static int getclassspec(int initialtok,int *fpublic,int *fstatic,int *fstock,int *fconst)
{
int tok,err;
@ -1600,6 +1622,9 @@ static void parse(void)
declglb(NULL,0,fpublic,fstatic,fstock,fconst);
break;
case tSTATIC:
if (matchtoken(tENUM)) {
decl_enum(sGLOBAL,TRUE);
} else {
/* This can be a static function or a static global variable; we know
* which of the two as soon as we have parsed up to the point where an
* opening paranthesis of a function would be expected. To back out after
@ -1610,12 +1635,13 @@ static void parse(void)
assert(!fpublic);
declfuncvar(fpublic,fstatic,fstock,fconst);
} /* if */
} /* if */
break;
case tCONST:
decl_const(sGLOBAL);
break;
case tENUM:
decl_enum(sGLOBAL);
decl_enum(sGLOBAL,matchtoken(tSTATIC));
break;
case tPUBLIC:
/* This can be a public function or a public variable; see the comment
@ -2181,7 +2207,7 @@ static int declloc(int fstatic)
* of a global variable or to that of a local variable at a lower
* level might indicate a bug.
*/
if ((sym=findloc(name))!=NULL && sym->compound!=nestlevel || findglb(name,sGLOBAL)!=NULL)
if (((sym=findloc(name))!=NULL && sym->compound!=nestlevel) || findglb(name,sGLOBAL)!=NULL)
error(219,name); /* variable shadows another symbol */
while (matchtoken('[')){
ident=iARRAY;
@ -2430,12 +2456,18 @@ static void initials(int ident,int tag,cell *size,int dim[],int numdim,
constvalue lastdim={NULL,"",0,0}; /* sizes of the final dimension */
int skipdim=0;
if (dim[numdim-1]!=0)
*size=calc_arraysize(dim,numdim,0); /* calc. full size, if known */
/* check if size specified for all dimensions */
for (idx=0; idx<numdim; idx++)
if (dim[idx]==0)
break;
/* already reserve space for the indirection tables (for an array with
* known dimensions)
* (do not use dumpzero(), as it bypasses the literal queue)
*/
if(idx==numdim)
*size=calc_arraysize(dim,numdim,0);
else
*size=0; /* size of one or more dimensions is unknown */
for (tablesize=calc_arraysize(dim,numdim-1,0); tablesize>0; tablesize--)
litadd(0);
/* now initialize the sub-arrays */
@ -2489,7 +2521,7 @@ static cell initarray(int ident,int tag,int dim[],int numdim,int cur,
constvalue *enumroot,int *errorfound)
{
cell dsize,totalsize;
int idx,idx_ellips,vidx;
int idx,idx_ellips,vidx,do_insert;
int abortparse;
int curlit;
cell *prev1=NULL,*prev2=NULL;
@ -2500,6 +2532,12 @@ static cell initarray(int ident,int tag,int dim[],int numdim,int cur,
assert(errorfound!=NULL && *errorfound==FALSE);
totalsize=0;
needtoken('{');
for (do_insert=0,idx=0; idx<=cur; idx++) {
if (dim[idx]==0) {
do_insert=TRUE;
break;
} /* if */
} /* for */
for (idx=0,abortparse=FALSE; !abortparse; idx++) {
/* In case the major dimension is zero, we need to store the offset
* to the newly detected sub-array into the indirection table; i.e.
@ -2509,7 +2547,7 @@ static cell initarray(int ident,int tag,int dim[],int numdim,int cur,
* necessary at this point to reserve space for an extra cell in the
* indirection vector.
*/
if (dim[cur]==0) {
if (do_insert) {
litinsert(0,startlit);
} else if (idx>=dim[cur]) {
error(18); /* initialization data exceeds array size */
@ -2768,7 +2806,7 @@ static void decl_const(int vclass)
/* decl_enum - declare enumerated constants
*
*/
static void decl_enum(int vclass)
static void decl_enum(int vclass,int fstatic)
{
char enumname[sNAMEMAX+1],constname[sNAMEMAX+1];
cell val,value,size;
@ -2777,6 +2815,9 @@ static void decl_enum(int vclass)
cell increment,multiplier;
constvalue *enumroot;
symbol *enumsym;
short filenum;
filenum=fcurrent;
/* get an explicit tag, if any (we need to remember whether an explicit
* tag was passed, even if that explicit tag was "_:", so we cannot call
@ -2820,8 +2861,11 @@ static void decl_enum(int vclass)
if (strlen(enumname)>0) {
/* already create the root symbol, so the fields can have it as their "parent" */
enumsym=add_constant(enumname,0,vclass,tag);
if (enumsym!=NULL)
if (enumsym!=NULL) {
enumsym->usage |= uENUMROOT;
if (fstatic)
enumsym->fnumber=filenum;
}
/* start a new list for the element names */
if ((enumroot=(constvalue*)malloc(sizeof(constvalue)))==NULL)
error(103); /* insufficient memory (fatal error) */
@ -2868,6 +2912,10 @@ static void decl_enum(int vclass)
sym->dim.array.length=size;
sym->dim.array.level=0;
sym->parent=enumsym;
if (fstatic)
sym->fnumber=filenum;
/* add the constant to a separate list as well */
if (enumroot!=NULL) {
sym->usage |= uENUMFIELD;
@ -3179,7 +3227,7 @@ static int operatoradjust(int opertok,symbol *sym,char *opername,int resulttag)
error(62); /* number or placement of the operands does not fit the operator */
} /* switch */
if (tags[0]==0 && (opertok!='=' && tags[1]==0 || opertok=='=' && resulttag==0))
if (tags[0]==0 && ((opertok!='=' && tags[1]==0) || (opertok=='=' && resulttag==0)))
error(64); /* cannot change predefined operators */
/* change the operator name */
@ -3324,21 +3372,19 @@ SC_FUNC char *funcdisplayname(char *dest,char *funcname)
static void check_reparse(symbol *sym)
{
/* if the function was used before being declared, add a third pass (as
* second "skimming" parse) because:
*
* - the function result may have been used with user-defined operators,
* which have now been incorrectly flagged (as the return tag was unknown
* at the time of the call)
*
* - one or more of the function's arguments involve global variables that
* have been declared before the function; in this situation the arguments
* are uknown at the time the funtion is called, so the variable may not
* be marked as read (uREAD) and may therefore be omitted from the
* resulting P-code
/* if the function was used before being declared, and it has a tag for the
* result, add a third pass (as second "skimming" parse) because the function
* result may have been used with user-defined operators, which have now
* been incorrectly flagged (as the return tag was unknown at the time of
* the call)
*/
if ((sym->usage & (uPROTOTYPED | uREAD))==uREAD)
if ((sym->usage & (uPROTOTYPED | uREAD))==uREAD && sym->tag!=0) {
int curstatus=sc_status;
sc_status=statWRITE; /* temporarily set status to WRITE, so the warning isn't blocked */
error(208);
sc_status=curstatus;
sc_reparse=TRUE; /* must add another pass to "initial scan" phase */
} /* if */
}
static void funcstub(int fnative)
@ -3381,7 +3427,7 @@ static void funcstub(int fnative)
tok=lex(&val,&str);
fpublic=(tok==tPUBLIC) || (tok==tSYMBOL && str[0]==PUBLIC_CHAR);
if (fnative) {
if (fpublic || tok==tSTOCK || tok==tSTATIC || tok==tSYMBOL && *str==PUBLIC_CHAR)
if (fpublic || tok==tSTOCK || tok==tSTATIC || (tok==tSYMBOL && *str==PUBLIC_CHAR))
error(42); /* invalid combination of class specifiers */
} else {
if (tok==tPUBLIC || tok==tSTOCK || tok==tSTATIC)
@ -3506,7 +3552,7 @@ static int newfunc(char *firstname,int firsttag,int fpublic,int fstatic,int stoc
tag= (firsttag>=0) ? firsttag : pc_addtag(NULL);
tok=lex(&val,&str);
assert(!fpublic);
if (tok==tNATIVE || tok==tPUBLIC && stock)
if (tok==tNATIVE || (tok==tPUBLIC && stock))
error(42); /* invalid combination of class specifiers */
if (tok==tOPERATOR) {
opertok=operatorname(symbolname);
@ -3741,7 +3787,7 @@ static int declargs(symbol *sym,int chkshadow)
ident=iVARIABLE;
numtags=0;
fconst=FALSE;
fpublic=(sym->usage & uPUBLIC)!=0;
fpublic= (sym->usage & uPUBLIC)!=0;
/* the '(' parantheses has already been parsed */
if (!matchtoken(')')){
do { /* there are arguments; process them */
@ -3855,7 +3901,7 @@ static int declargs(symbol *sym,int chkshadow)
error(10); /* illegal function or declaration */
} /* switch */
} while (tok=='&' || tok==tLABEL || tok==tCONST
|| tok!=tELLIPS && matchtoken(',')); /* more? */
|| (tok!=tELLIPS && matchtoken(','))); /* more? */
/* if the next token is not ",", it should be ")" */
needtoken(')');
} /* if */
@ -4885,9 +4931,9 @@ SC_FUNC symbol *add_constant(char *name,cell val,int vclass,int tag)
* constants are stored in the symbols table, this also finds previously
* defind constants. */
sym=findglb(name,sSTATEVAR);
if (!sym)
if (sym==NULL)
sym=findloc(name);
if (sym) {
if (sym!=NULL) {
int redef=0;
if (sym->ident!=iCONSTEXPR)
redef=1; /* redefinition a function/variable to a constant is not allowed */
@ -4929,8 +4975,61 @@ SC_FUNC symbol *add_constant(char *name,cell val,int vclass,int tag)
redef_enumfield:
sym=addsym(name,val,iCONSTEXPR,vclass,tag,uDEFINE);
assert(sym!=NULL); /* fatal error 103 must be given on error */
if (sc_status == statIDLE)
sym->usage |= uPREDEF;
return sym;
}
/* add_builtin_constant
*
* Adds a predefined constant to the symbol table.
*/
SC_FUNC symbol *add_builtin_constant(char *name,cell val,int vclass,int tag)
{
symbol *sym;
sym=add_constant(name,val,vclass,tag);
sym->flags|=flagPREDEF;
return sym;
}
/* add_builtin_string_constant
*
* Adds a predefined string constant to the symbol table.
*/
SC_FUNC symbol *add_builtin_string_constant(char *name,const char *val,
int vclass)
{
symbol *sym;
/* Test whether a global or local symbol with the same name exists. Since
* constants are stored in the symbols table, this also finds previously
* defind constants. */
sym=findglb(name,sSTATEVAR);
if (sym==NULL)
sym=findloc(name);
if (sym!=NULL) {
if (sym->ident!=iARRAY) {
error(21,name); /* symbol already defined */
return NULL;
} /* if */
} else {
sym=addsym(name,0,iARRAY,vclass,0,uDEFINE | uSTOCK);
} /* if */
sym->addr=(litidx+glb_declared)*sizeof(cell);
/* Store this constant only if it's used somewhere. This can be detected
* in the second stage. */
if (sc_status==statIDLE
|| (sc_status==statWRITE && (sym->usage & uREAD)!=0)) {
assert(litidx==0);
begdseg();
while (*val!='\0')
litadd(*val++);
litadd(0);
glb_declared+=litidx;
dumplits();
litidx=0;
}
sym->usage|=uDEFINE;
sym->flags|=flagPREDEF;
return sym;
}
@ -4976,7 +5075,9 @@ static void statement(int *lastindent,int allow_decl)
} /* if */
break;
case tSTATIC:
if (allow_decl) {
if (matchtoken(tENUM))
decl_enum(sLOCAL,FALSE);
else if (allow_decl) {
declloc(TRUE);
lastst=tNEW;
} else {
@ -5053,7 +5154,8 @@ static void statement(int *lastindent,int allow_decl)
decl_const(sLOCAL);
break;
case tENUM:
decl_enum(sLOCAL);
matchtoken(tSTATIC);
decl_enum(sLOCAL,FALSE);
break;
default: /* non-empty expression */
sc_allowproccall=optproccall;
@ -5734,7 +5836,7 @@ static void doreturn(void)
if ((rettype & uRETVALUE)!=0) {
int retarray=(ident==iARRAY || ident==iREFARRAY);
/* there was an earlier "return" statement in this function */
if ((sub==NULL && retarray && sym!=NULL) || sub!=NULL && !retarray)
if ((sub==NULL && retarray && sym!=NULL) || (sub!=NULL && !retarray))
error(79); /* mixing "return array;" and "return value;" */
if (retarray && (curfunc->usage & uPUBLIC)!=0)
error(90,curfunc->name); /* public function may not return array */
@ -5745,7 +5847,7 @@ static void doreturn(void)
if (!matchtag(curfunc->tag,tag,TRUE))
error(213); /* tagname mismatch */
if (ident==iARRAY || ident==iREFARRAY) {
int dim[sDIMEN_MAX],numdim;
int dim[sDIMEN_MAX],numdim=0;
cell arraysize;
if (sym==NULL) {
/* array literals cannot be returned directly */

View File

@ -198,6 +198,7 @@ static char extensions[][6] = { "", ".inc", ".p", ".pawn" };
icomment=0; /* not in a comment */
insert_dbgfile(inpfname);
setfiledirect(inpfname);
setfileconst(inpfname);
listline=-1; /* force a #line directive when changing the file */
sc_is_utf8=(short)scan_utf8(inpf,real_path);
free(real_path);
@ -350,7 +351,6 @@ static void readline(unsigned char *line)
{
int i,num,cont;
unsigned char *ptr;
symbol *sym;
if (lptr==term_expr)
return;
@ -358,7 +358,6 @@ static void readline(unsigned char *line)
cont=FALSE;
do {
if (inpf==NULL || pc_eofsrc(inpf)) {
pc_writeasm(outf,"\n"); /* insert a newline at the end of file */
if (cont)
error(49); /* invalid line continuation */
if (inpf!=NULL && inpf!=inpf_org)
@ -429,9 +428,7 @@ static void readline(unsigned char *line)
line+=strlen((char*)line);
} /* if */
fline+=1;
sym=findconst("__line",NULL);
assert(sym!=NULL);
sym->addr=fline;
setlineconst(fline);
} while (num>=0 && cont);
}
@ -484,7 +481,7 @@ static void stripcom(unsigned char *line)
#if !defined SC_LIGHT
/* collect the comment characters in a string */
if (icomment==2) {
if (skipstar && (*line!='\0' && *line<=' ' || *line=='*')) {
if (skipstar && ((*line!='\0' && *line<=' ') || *line=='*')) {
/* ignore leading whitespace and '*' characters */
} else if (commentidx<COMMENT_LIMIT+COMMENT_MARGIN-1) {
comment[commentidx++]=(char)((*line!='\n') ? *line : ' ');
@ -1314,7 +1311,7 @@ static int command(void)
sym=findloc(str);
if (sym==NULL)
sym=findglb(str,sSTATEVAR);
if (sym==NULL || sym->ident!=iFUNCTN && sym->ident!=iREFFUNC && (sym->usage & uDEFINE)==0) {
if (sym==NULL || (sym->ident!=iFUNCTN && sym->ident!=iREFFUNC && (sym->usage & uDEFINE)==0)) {
error(17,str); /* undefined symbol */
} else {
if (sym->ident==iFUNCTN || sym->ident==iREFFUNC) {
@ -1787,7 +1784,7 @@ static void substallpatterns(unsigned char *line,int buffersize)
if (strncmp((char*)start,"defined",7)==0 && *(start+7)<=' ') {
start+=7; /* skip "defined" */
/* skip white space & parantheses */
while (*start<=' ' && *start!='\0' || *start=='(')
while ((*start<=' ' && *start!='\0') || *start=='(')
start++;
/* skip the symbol behind it */
while (alphanum(*start))
@ -2201,11 +2198,11 @@ SC_FUNC int lex(cell *lexvalue,char **lexsym)
error(220);
} /* if */
} /* if */
} else if (*lptr=='\"' || *lptr=='#' || *lptr==sc_ctrlchar && (*(lptr+1)=='\"' || *(lptr+1)=='#'))
} else if (*lptr=='\"' || *lptr=='#' || (*lptr==sc_ctrlchar && (*(lptr+1)=='\"' || *(lptr+1)=='#')))
{ /* unpacked string literal */
_lextok=tSTRING;
stringflags= (*lptr==sc_ctrlchar) ? RAWMODE : 0;
stringflags |= (*lptr=='#' || (*lptr==sc_ctrlchar && *(lptr+1)=='#')) ? STRINGIZE : 0;
stringflags=(*lptr==sc_ctrlchar) ? RAWMODE : 0;
stringflags|=(*lptr=='#' || (*lptr==sc_ctrlchar && *(lptr+1)=='#')) ? STRINGIZE : 0;
*lexvalue=_lexval=litidx;
lptr+=1; /* skip double quote */
if ((stringflags & RAWMODE)!=0)
@ -2215,9 +2212,9 @@ SC_FUNC int lex(cell *lexvalue,char **lexsym)
lptr+=1; /* skip final quote */
else if (!(stringflags & STRINGIZE))
error(37); /* invalid (non-terminated) string */
} else if (*lptr=='!' && (*(lptr+1)=='\"' || *(lptr+1)=='#')
|| *lptr=='!' && *(lptr+1)==sc_ctrlchar && (*(lptr+2)=='\"' || *(lptr+2)=='#')
|| *lptr==sc_ctrlchar && *(lptr+1)=='!' && (*(lptr+2)=='\"' || *(lptr+2)=='#'))
} else if ((*lptr=='!' && (*(lptr+1)=='\"' || *(lptr+1)=='#'))
|| (*lptr=='!' && *(lptr+1)==sc_ctrlchar && (*(lptr+2)=='\"' || *(lptr+2)=='#'))
|| (*lptr==sc_ctrlchar && *(lptr+1)=='!' && (*(lptr+2)=='\"' || *(lptr+2)=='#')))
{ /* packed string literal */
_lextok=tSTRING;
stringflags=0;
@ -2315,7 +2312,7 @@ SC_FUNC int matchtoken(int token)
int tok;
tok=lex(&val,&str);
if (tok==token || token==tTERM && (tok==';' || tok==tENDEXPR)) {
if (tok==token || (token==tTERM && (tok==';' || tok==tENDEXPR))) {
return 1;
} else if (!sc_needsemicolon && token==tTERM && (_lexnewline || !freading)) {
/* Push "tok" back, because it is the token following the implicit statement
@ -2749,7 +2746,7 @@ SC_FUNC void delete_symbols(symbol *root,int level,int delete_labels,int delete_
assert(0);
break;
} /* switch */
if (mustdelete) {
if (mustdelete && (sym->flags & flagPREDEF)==0) {
root->next=sym->next;
free_symbol(sym);
} else {
@ -2758,7 +2755,8 @@ SC_FUNC void delete_symbols(symbol *root,int level,int delete_labels,int delete_
*/
if (sym->ident==iFUNCTN && (sym->usage & uDEFINE)==0)
sym->usage |= uMISSING;
if (sym->ident==iFUNCTN || sym->ident==iVARIABLE || sym->ident==iARRAY)
if ((sym->ident==iFUNCTN || sym->ident==iVARIABLE || sym->ident==iARRAY)
&& (sym->flags & flagPREDEF)==0)
sym->usage &= ~uDEFINE; /* clear "defined" flag */
/* set all states as "undefined" too */
if (sym->states!=NULL)
@ -2771,7 +2769,7 @@ SC_FUNC void delete_symbols(symbol *root,int level,int delete_labels,int delete_
sym->usage &= ~uPROTOTYPED;
root=sym; /* skip the symbol */
} /* if */
} /* if */
} /* while */
}
/* The purpose of the hash is to reduce the frequency of a "name"
@ -2801,8 +2799,8 @@ static symbol *find_symbol(const symbol *root,const char *name,int fnumber,int a
{
assert(sym->states==NULL || sym->states->next!=NULL); /* first element of the state list is the "root" */
if (sym->ident==iFUNCTN
|| automaton<0 && sym->states==NULL
|| automaton>=0 && sym->states!=NULL && state_getfsa(sym->states->next->index)==automaton)
|| (automaton<0 && sym->states==NULL)
|| (automaton>=0 && sym->states!=NULL && state_getfsa(sym->states->next->index)==automaton))
{
if (cmptag==NULL && sym->fnumber==fnumber)
return sym; /* return first match */

View File

@ -592,8 +592,8 @@ static void plnge2(void (*oper)(void),
* has no side effects. This may not be accurate, but it does allow
* the compiler to check the effect of the entire expression.
*/
if (lval1->sym!=NULL && (lval1->sym->ident==iFUNCTN || lval1->sym->ident==iREFFUNC)
|| lval2->sym!=NULL && (lval2->sym->ident==iFUNCTN || lval2->sym->ident==iREFFUNC))
if ((lval1->sym!=NULL && (lval1->sym->ident==iFUNCTN || lval1->sym->ident==iREFFUNC))
|| (lval2->sym!=NULL && (lval2->sym->ident==iFUNCTN || lval2->sym->ident==iREFFUNC)))
pc_sideeffect=FALSE;
if (lval1->ident==iARRAY || lval1->ident==iREFARRAY) {
char *ptr=(lval1->sym!=NULL) ? lval1->sym->name : "-unknown-";
@ -820,7 +820,7 @@ static int hier14(value *lval1)
* negative value would do).
*/
for (i=0; i<sDIMEN_MAX; i++)
arrayidx1[i]=arrayidx2[i]=(cell)(-1L << (sizeof(cell)*8-1));
arrayidx1[i]=arrayidx2[i]=(cell)CELL_MAX;
org_arrayidx=lval1->arrayidx; /* save current pointer, to reset later */
if (lval1->arrayidx==NULL)
lval1->arrayidx=arrayidx1;
@ -921,13 +921,14 @@ static int hier14(value *lval1)
{
int same=TRUE;
assert(lval2.arrayidx==arrayidx2);
for (i=0; i<sDIMEN_MAX; i++)
for (i=0; i<sDIMEN_MAX; i++) {
same=same && (lval3.arrayidx[i]==lval2.arrayidx[i]);
} /* for */
if (same)
error(226,lval3.sym->name); /* self-assignment */
} /* if */
} else {
if (oper){
if (oper) {
rvalue(lval1);
plnge2(oper,hier14,lval1,&lval2);
} else {
@ -936,7 +937,7 @@ static int hier14(value *lval1)
if (hier14(&lval2))
rvalue(&lval2); /* instead of plnge2(). */
else if (lval2.ident==iVARIABLE)
lval2.ident=iEXPRESSION;/* mark as "rvalue" if it is not an "lvalue" */
lval2.ident=iEXPRESSION; /* mark as "rvalue" if it is not an "lvalue" */
checkfunction(&lval2);
/* check whether lval2 and lval3 (old lval1) refer to the same variable */
if (lval2.ident==iVARIABLE && lval3.ident==lval2.ident && lval3.sym==lval2.sym) {
@ -1001,7 +1002,7 @@ static int hier14(value *lval1)
} /* if */
if (lval3.sym->dim.array.level!=level)
return error(48); /* array dimensions must match */
else if (ltlength<val || exactmatch && ltlength>val || val==0)
else if (ltlength<val || (exactmatch && ltlength>val) || val==0)
return error(47); /* array sizes must match */
else if (lval3.ident!=iARRAYCELL && !matchtag(lval3.sym->x.tags.index,idxtag,TRUE))
error(229,(lval2.sym!=NULL) ? lval2.sym->name : lval3.sym->name); /* index tag mismatch */
@ -1250,6 +1251,8 @@ static int hier2(value *lval)
rvalue(lval);
invert(); /* bitwise NOT */
lval->constval=~lval->constval;
if (lval->ident==iVARIABLE || lval->ident==iARRAYCELL)
lval->ident=iEXPRESSION;
return FALSE;
case '!': /* ! (logical negate) */
if (hier2(lval))
@ -1261,6 +1264,8 @@ static int hier2(value *lval)
lneg(); /* 0 -> 1, !0 -> 0 */
lval->constval=!lval->constval;
lval->tag=pc_addtag("bool");
if (lval->ident==iVARIABLE || lval->ident==iARRAYCELL)
lval->ident=iEXPRESSION;
} /* if */
return FALSE;
case '-': /* unary - (two's complement) */
@ -1289,6 +1294,8 @@ static int hier2(value *lval)
} else {
neg(); /* arithmic negation */
lval->constval=-lval->constval;
if (lval->ident==iVARIABLE || lval->ident==iARRAYCELL)
lval->ident=iEXPRESSION;
} /* if */
return FALSE;
case tLABEL: /* tagname override */
@ -1588,7 +1595,7 @@ restart:
} /* if */
if (close==']') {
/* normal array index */
if (lval2.constval<0 || sym->dim.array.length!=0 && sym->dim.array.length<=lval2.constval)
if (lval2.constval<0 || (sym->dim.array.length!=0 && sym->dim.array.length<=lval2.constval))
error(32,sym->name); /* array index out of bounds */
if (lval2.constval!=0) {
/* don't add offsets for zero subscripts */
@ -1605,8 +1612,9 @@ restart:
} /* if */
} else {
/* character index */
if (lval2.constval<0 || sym->dim.array.length!=0
&& sym->dim.array.length*((8*sizeof(cell))/sCHARBITS)<=(ucell)lval2.constval)
if (lval2.constval<0
|| (sym->dim.array.length!=0
&& sym->dim.array.length*((8*sizeof(cell))/sCHARBITS)<=(ucell)lval2.constval))
error(32,sym->name); /* array index out of bounds */
if (lval2.constval!=0) {
/* don't add offsets for zero subscripts */
@ -2077,7 +2085,14 @@ static int nesting=0;
if (arg[argidx].ident!=0 && arg[argidx].numtags==1)
lval.cmptag=arg[argidx].tags[0]; /* set the expected tag, if any */
lvalue=hier14(&lval);
assert(sc_status==statFIRST || arg[argidx].ident== 0 || arg[argidx].tags!=NULL);
/* Mark the symbol as "read" so it won't be omitted from P-code.
* Native functions are marked as read at the point of their call,
* so we don't handle them here; see ffcall().
*/
if (lval.sym!=NULL && (lval.sym->usage & uNATIVE)==0) {
markusage(lval.sym,uREAD);
} /* if */
assert(sc_status==statFIRST || arg[argidx].ident==0 || arg[argidx].tags!=NULL);
switch (arg[argidx].ident) {
case 0:
error(202); /* argument count mismatch */
@ -2190,8 +2205,8 @@ static int nesting=0;
* function argument; a literal string may be smaller than
* the function argument.
*/
if (lval.constval>0 && arg[argidx].dim[0]!=lval.constval
|| lval.constval<0 && arg[argidx].dim[0] < -lval.constval)
if ((lval.constval>0 && arg[argidx].dim[0]!=lval.constval)
|| (lval.constval<0 && arg[argidx].dim[0] < -lval.constval))
error(47); /* array sizes must match */
} /* if */
} /* if */

View File

@ -249,7 +249,7 @@ SC_FUNC void setline(int chkbounds)
stgwrite("\t; line ");
outval(fline,TRUE);
} /* if */
if ((sc_debug & sSYMBOLIC)!=0 || chkbounds && (sc_debug & sCHKBOUNDS)!=0) {
if ((sc_debug & sSYMBOLIC)!=0 || (chkbounds && (sc_debug & sCHKBOUNDS)!=0)) {
/* generate a "break" (start statement) opcode rather than a "line" opcode
* because earlier versions of Small/Pawn have an incompatible version of the
* line opcode
@ -264,12 +264,20 @@ SC_FUNC void setfiledirect(char *name)
{
if (sc_status==statFIRST && sc_listing) {
assert(name!=NULL);
pc_writeasm(outf,"#file \"");
pc_writeasm(outf,"\n#file \"");
pc_writeasm(outf,name);
pc_writeasm(outf,"\"\n");
} /* if */
}
SC_FUNC void setfileconst(char *name)
{
symbol *sym;
sym=add_builtin_string_constant("__file",name,sGLOBAL);
sym->fnumber=fcurrent;
}
SC_FUNC void setlinedirect(int line)
{
if (sc_status==statFIRST && sc_listing) {
@ -279,6 +287,15 @@ SC_FUNC void setlinedirect(int line)
} /* if */
}
SC_FUNC void setlineconst(int line)
{
symbol *sym;
sym=findconst("__line",NULL);
assert(sym!=NULL);
sym->addr=fline;
}
/* setlabel
*
* Post a code label (specified as a number), on a new line.
@ -758,7 +775,7 @@ SC_FUNC void ffcall(symbol *sym,const char *label,int numargs)
stgwrite(sym->name);
} /* if */
if (sc_asmfile
&& (label!=NULL || !isalpha(sym->name[0]) && sym->name[0]!='_' && sym->name[0]!=sc_ctrlchar))
&& (label!=NULL || (!isalpha(sym->name[0]) && sym->name[0]!='_' && sym->name[0]!=sc_ctrlchar)))
{
stgwrite("\t; ");
stgwrite(symname);

View File

@ -283,7 +283,7 @@ static short lastfile;
} /* if */
va_end(argptr);
if (number>=100 && number<200 || errnum>25){
if ((number>=100 && number<200) || errnum>25){
if (strlen(errfname)==0) {
va_start(argptr,number);
pc_error(0,"\nCompilation aborted.\n\n",NULL,0,0,argptr);

View File

@ -218,9 +218,9 @@ static char *stripwhitespace(char *str)
if (*str!='\0') {
size_t len = strlen(str);
size_t i;
for (i=len-1; i>=0; i--) {
if (!isspace(str[i])) {
str[i+1]='\0';
for (i=len; i>=1; i--) {
if (!isspace(str[i-1])) {
str[i]='\0';
break;
}
}
@ -1027,7 +1027,7 @@ SC_FUNC int assemble(FILE *fout,FILE *fin)
instr=skipwhitespace(line);
/* ignore empty lines and labels (labels have a special syntax, so these
* must be parsed separately) */
if (*instr=='\0' || tolower(*instr)=='l' && *(instr+1)=='.')
if (*instr=='\0' || (tolower(*instr)=='l') && *(instr+1)=='.')
continue;
/* get to the end of the instruction (make use of the '\n' that fgets()
* added at the end of the line; this way we will *always* drop on a

View File

@ -1642,7 +1642,7 @@ static int matchsequence(char *start,char *end,char *pattern,
assert(*(start+1)=='\0');
start+=2; /* skip '\n' and '\0' */
if (*(pattern+1)!='\0')
while (start<end && *start=='\t' || *start==' ')
while ((start<end && *start=='\t') || *start==' ')
start++; /* skip leading white space of next instruction */
break;
default:
@ -1691,8 +1691,10 @@ static char *replacesequence(char *pattern,char symbols[MAX_OPT_VARS][MAX_ALIAS+
} /* while */
/* allocate a buffer to replace the sequence in */
if ((buffer=(char*)malloc(*repl_length))==NULL)
return (char*)error(103);
if ((buffer=(char*)malloc(*repl_length))==NULL) {
error(103);
return NULL;
} /* if */
/* replace the pattern into this temporary buffer */
lptr=buffer;

View File

@ -339,7 +339,7 @@ SC_FUNC cell get_utf8_char(const unsigned char *string,const unsigned char **end
/* the code positions 0xd800--0xdfff and 0xfffe & 0xffff do not
* exist in UCS-4 (and hence, they do not exist in Unicode)
*/
if (result>=0xd800 && result<=0xdfff || result==0xfffe || result==0xffff)
if ((result>=0xd800 && result<=0xdfff) || result==0xfffe || result==0xffff)
return -1;
} /* if */
break;

View File

@ -1,4 +1,5 @@
#define VERSION_MINOR @VERSION_MINOR@
#define VERSION_MAJOR @VERSION_MAJOR@
#define VERSION_BUILD @VERSION_BUILD@
#define VERSION_STR "@VERSION_STR@"
#define VERSION_INT @VERSION_INT@

View File

@ -25,6 +25,10 @@
#define DIRECTORY_SEP_CHAR '/'
#define DIRECTORY_SEP_STR "/"
#if defined HAVE_ENDIAN_H
# include <endian.h>
#endif
/*
* SC assumes that a computer is Little Endian unless told otherwise. It uses
* (and defines) the macros BYTE_ORDER and BIG_ENDIAN.