__pragma: Move the string processing code into a separate function, so it could be reused by other operators
This commit is contained in:
parent
a68bacf86e
commit
3dfad1f7fd
@ -143,6 +143,7 @@ static void dostate(void);
|
||||
static void addwhile(int *ptr);
|
||||
static void delwhile(void);
|
||||
static int *readwhile(void);
|
||||
static char *parsestringparam(int onlycheck,int *bck_litidx);
|
||||
static void dopragma(void);
|
||||
static void pragma_apply(symbol *sym);
|
||||
|
||||
@ -8284,10 +8285,86 @@ static int *readwhile(void)
|
||||
} /* if */
|
||||
}
|
||||
|
||||
static void dopragma(void)
|
||||
/* parsestringparam()
|
||||
*
|
||||
* Uses the standard string parsing mechanism to parse string parameters
|
||||
* for operator '__pragma'.
|
||||
*/
|
||||
static char *parsestringparam(int onlycheck,int *bck_litidx)
|
||||
{
|
||||
int tok;
|
||||
int bck_litidx,bck_packstr;
|
||||
int bck_packstr;
|
||||
cell val;
|
||||
char *str;
|
||||
|
||||
assert(bck_litidx!=NULL);
|
||||
|
||||
/* back up 'litidx', so we can remove the string from the literal queue later */
|
||||
*bck_litidx=litidx;
|
||||
/* force the string to be packed by default, so it would be easier to process it */
|
||||
bck_packstr=sc_packstr;
|
||||
sc_packstr=TRUE;
|
||||
|
||||
/* read the string parameter */
|
||||
tok=lex(&val,&str);
|
||||
sc_packstr=bck_packstr;
|
||||
if (tok!=tSTRING || !pc_ispackedstr) {
|
||||
/* either not a string, or the user prepended "!" to the option string */
|
||||
char tokstr[2];
|
||||
if (tok==tSTRING) {
|
||||
tok='!';
|
||||
litidx=*bck_litidx; /* remove the string from the literal queue */
|
||||
} /* if */
|
||||
if (tok<tFIRST) {
|
||||
sprintf(tokstr,"%c",tok);
|
||||
str=tokstr;
|
||||
} else {
|
||||
str=sc_tokens[tok-tFIRST];
|
||||
} /* if */
|
||||
error(1,sc_tokens[tSTRING-tFIRST],str);
|
||||
return NULL;
|
||||
} /* if */
|
||||
assert(litidx>*bck_litidx);
|
||||
|
||||
if (onlycheck) {
|
||||
/* skip the byte swapping and remove the string from the literal queue,
|
||||
* as the caller only needed to check if the string was valid */
|
||||
litidx=*bck_litidx;
|
||||
return NULL;
|
||||
} /* if */
|
||||
|
||||
/* swap the cell bytes if we're on a Little Endian platform */
|
||||
#if BYTE_ORDER==LITTLE_ENDIAN
|
||||
{ /* local */
|
||||
char *bytes;
|
||||
cell i=val;
|
||||
do {
|
||||
char t;
|
||||
bytes=(char *)&litq[i++];
|
||||
t=bytes[0], bytes[0]=bytes[sizeof(cell)-1], bytes[sizeof(cell)-1]=t;
|
||||
#if PAWN_CELL_SIZE>=32
|
||||
t=bytes[1], bytes[1]=bytes[sizeof(cell)-2], bytes[sizeof(cell)-2]=t;
|
||||
#if PAWN_CELL_SIZE==64
|
||||
t=bytes[2], bytes[2]=bytes[sizeof(cell)-3], bytes[sizeof(cell)-3]=t;
|
||||
t=bytes[3], bytes[3]=bytes[sizeof(cell)-4], bytes[sizeof(cell)-4]=t;
|
||||
#endif // PAWN_CELL_SIZE==64
|
||||
#endif // PAWN_CELL_SIZE>=32
|
||||
} while (bytes[0]!='\0' && bytes[1]!='\0'
|
||||
#if PAWN_CELL_SIZE>=32
|
||||
&& bytes[2]!='\0' && bytes[3]!='\0'
|
||||
#if PAWN_CELL_SIZE==64
|
||||
&& bytes[4]!='\0' && bytes[5]!='\0' && bytes[6]!='\0' && bytes[7]!='\0'
|
||||
#endif // PAWN_CELL_SIZE==64
|
||||
#endif // PAWN_CELL_SIZE>=32
|
||||
); /* do */
|
||||
} /* local */
|
||||
#endif
|
||||
return (char*)&litq[val];
|
||||
}
|
||||
|
||||
static void dopragma(void)
|
||||
{
|
||||
int bck_litidx;
|
||||
int i;
|
||||
cell val;
|
||||
char *str;
|
||||
@ -8300,60 +8377,13 @@ static void dopragma(void)
|
||||
* mechanism. This way, as a bonus, we'll also be able to use multi-line
|
||||
* strings and the stringization operator.
|
||||
*/
|
||||
/* first, back up litidx, so we can remove the string from the literal queue later */
|
||||
bck_litidx=litidx;
|
||||
/* also, force the string to be packed by default, so it would be easier to process it */
|
||||
bck_packstr=sc_packstr;
|
||||
sc_packstr=TRUE;
|
||||
|
||||
do {
|
||||
/* read the option string */
|
||||
tok=lex(&val,&str);
|
||||
if (tok!=tSTRING || !pc_ispackedstr) {
|
||||
/* either not a string, or the user prepended "!" to the option string */
|
||||
char tokstr[2];
|
||||
if (tok==tSTRING)
|
||||
tok='!';
|
||||
if (tok<tFIRST) {
|
||||
sprintf(tokstr,"%c",tok);
|
||||
str=tokstr;
|
||||
} else {
|
||||
str=sc_tokens[tok-tFIRST];
|
||||
} /* if */
|
||||
error(1,sc_tokens[tSTRING-tFIRST],str);
|
||||
goto next;
|
||||
} /* if */
|
||||
assert(litidx>bck_litidx);
|
||||
|
||||
/* swap the cell bytes if we're on a Little Endian platform */
|
||||
#if BYTE_ORDER==LITTLE_ENDIAN
|
||||
{ /* local */
|
||||
char *bytes;
|
||||
i=(int)val;
|
||||
do {
|
||||
char t;
|
||||
bytes=(char *)&litq[i++];
|
||||
t=bytes[0], bytes[0]=bytes[sizeof(cell)-1], bytes[sizeof(cell)-1]=t;
|
||||
#if PAWN_CELL_SIZE>=32
|
||||
t=bytes[1], bytes[1]=bytes[sizeof(cell)-2], bytes[sizeof(cell)-2]=t;
|
||||
#if PAWN_CELL_SIZE==64
|
||||
t=bytes[2], bytes[2]=bytes[sizeof(cell)-3], bytes[sizeof(cell)-3]=t;
|
||||
t=bytes[3], bytes[3]=bytes[sizeof(cell)-4], bytes[sizeof(cell)-4]=t;
|
||||
#endif // PAWN_CELL_SIZE==64
|
||||
#endif // PAWN_CELL_SIZE>=32
|
||||
} while (bytes[0]!='\0' && bytes[1]!='\0'
|
||||
#if PAWN_CELL_SIZE>=32
|
||||
&& bytes[2]!='\0' && bytes[3]!='\0'
|
||||
#if PAWN_CELL_SIZE==64
|
||||
&& bytes[4]!='\0' && bytes[5]!='\0' && bytes[6]!='\0' && bytes[7]!='\0'
|
||||
#endif // PAWN_CELL_SIZE==64
|
||||
#endif // PAWN_CELL_SIZE>=32
|
||||
); /* do */
|
||||
} /* local */
|
||||
#endif
|
||||
|
||||
str=parsestringparam(FALSE,&bck_litidx);
|
||||
if (str==NULL)
|
||||
continue;
|
||||
|
||||
/* split the option name from parameters */
|
||||
str=(char*)&litq[val];
|
||||
for (i=0; str[i]!='\0' && str[i]!=' '; i++)
|
||||
/* nothing */;
|
||||
if (str[i]!='\0') {
|
||||
@ -8417,13 +8447,11 @@ unknown_pragma:
|
||||
error(207); /* unknown #pragma */
|
||||
} /* if */
|
||||
|
||||
next:
|
||||
/* remove the string from the literal queue */
|
||||
litidx=bck_litidx;
|
||||
} while (matchtoken(','));
|
||||
|
||||
needtoken(')');
|
||||
sc_packstr=bck_packstr;
|
||||
}
|
||||
|
||||
static void pragma_apply(symbol *sym)
|
||||
|
Loading…
x
Reference in New Issue
Block a user