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
This commit is contained in:
Zeex 2014-01-05 02:08:24 +07:00
parent 53221dd2cc
commit 634f40953b
3 changed files with 63 additions and 6 deletions

View File

@ -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)

View File

@ -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 */

View File

@ -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