From 634f40953bd331deaf32143bfd7feee07d977a1f Mon Sep 17 00:00:00 2001 From: Zeex Date: Sun, 5 Jan 2014 02:08:24 +0700 Subject: [PATCH] Introduce #pragma warning This pragma lets you to enable or disable a specific warning by its unique number (same as in error messages). Syntax: #pragma warning (push|pop|enable XXX|disable XXX) #pragma warning push - save current warnings #pragma warning pop - restore warnings #pragma warning enable XXX - enable warning XXX #pragma warning disable XXX - disable warning XXX --- source/compiler/sc.h | 2 ++ source/compiler/sc2.c | 22 +++++++++++++++++++++ source/compiler/sc5.c | 45 +++++++++++++++++++++++++++++++++++++------ 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/source/compiler/sc.h b/source/compiler/sc.h index 3395169..a3c0af3 100644 --- a/source/compiler/sc.h +++ b/source/compiler/sc.h @@ -458,6 +458,8 @@ int pc_compile(int argc, char **argv); int pc_addconstant(char *name,cell value,int tag); int pc_addtag(char *name); int pc_enablewarning(int number,int enable); +int pc_pushwarnings(); +int pc_popwarnings(); /* * Functions called from the compiler (to be implemented by you) diff --git a/source/compiler/sc2.c b/source/compiler/sc2.c index 113198b..55c8a8b 100644 --- a/source/compiler/sc2.c +++ b/source/compiler/sc2.c @@ -1170,6 +1170,28 @@ static int command(void) } while (comma); } else if (strcmp(str,"naked")==0) { pc_naked=TRUE; + } else if (strcmp(str,"warning")==0) { + int ok=lex(&val,&str)==tSYMBOL; + if (ok) { + if (strcmp(str,"enable")==0) { + cell val; + preproc_expr(&val,NULL); + pc_enablewarning(val,1); + } else if (strcmp(str,"disable")==0) { + cell val; + preproc_expr(&val,NULL); + pc_enablewarning(val,0); + } else if (strcmp(str,"push")==0) { + pc_pushwarnings(); + } else if (strcmp(str,"pop")==0) { + pc_popwarnings(); + } else { + ok=FALSE; + } + } + if (!ok) { + error(207); /* unknown #pragma */ + } } else { error(207); /* unknown #pragma */ } /* if */ diff --git a/source/compiler/sc5.c b/source/compiler/sc5.c index e87f7c1..992f3e9 100644 --- a/source/compiler/sc5.c +++ b/source/compiler/sc5.c @@ -49,7 +49,10 @@ #endif #define NUM_WARNINGS (sizeof warnmsg / sizeof warnmsg[0]) -static unsigned char warndisable[(NUM_WARNINGS + 7) / 8]; /* 8 flags in a char */ +static struct s_warnstack { + unsigned char disable[(NUM_WARNINGS + 7) / 8]; /* 8 flags in a char */ + struct s_warnstack *next; +} warnstack; static int errflag; static int errstart; /* line number at which the instruction started */ @@ -88,7 +91,7 @@ static short lastfile; if (number>=200) { int index=(number-200)/8; int mask=1 << ((number-200)%8); - if ((warndisable[index] & mask)!=0) + if ((warnstack.disable[index] & mask)!=0) return 0; } /* if */ @@ -187,7 +190,7 @@ SC_FUNC void errorset(int code,int line) } /* switch */ } -/* sc_enablewarning() +/* pc_enablewarning() * Enables or disables a warning (errors cannot be disabled). * Initially all warnings are enabled. The compiler does this by setting bits * for the *disabled* warnings and relying on the array to be zero-initialized. @@ -212,17 +215,47 @@ int pc_enablewarning(int number,int enable) mask=(unsigned char)(1 << (number%8)); switch (enable) { case 0: - warndisable[index] |= mask; + warnstack.disable[index] |= mask; break; case 1: - warndisable[index] &= (unsigned char)~mask; + warnstack.disable[index] &= (unsigned char)~mask; break; case 2: - warndisable[index] ^= mask; + warnstack.disable[index] ^= mask; break; } /* switch */ return TRUE; } +/* pc_pushwarnings() + * Saves currently disabled warnings, used to implement #pragma warning push + */ +int pc_pushwarnings() +{ + void *p; + p=calloc(sizeof(struct s_warnstack),1); + if (p==NULL) { + error(103); /* insufficient memory */ + return FALSE; + } + memmove(p,&warnstack,sizeof(struct s_warnstack)); + warnstack.next=p; + return TRUE; +} + +/* pc_popwarnings() + * This function is the reverse of pc_pushwarnings() + */ +int pc_popwarnings() +{ + void *p; + if (warnstack.next==NULL) + return FALSE; /* nothing to do */ + p=warnstack.next; + memmove(&warnstack,p,sizeof(struct s_warnstack)); + free(p); + return TRUE; +} + #undef SCPACK_TABLE