__pragma: Move the string processing code into a separate function, so it could be reused by other operators

This commit is contained in:
Stanislav Gromov 2020-11-15 00:52:04 +07:00
parent a68bacf86e
commit 3dfad1f7fd

View File

@ -143,6 +143,7 @@ static void dostate(void);
static void addwhile(int *ptr); static void addwhile(int *ptr);
static void delwhile(void); static void delwhile(void);
static int *readwhile(void); static int *readwhile(void);
static char *parsestringparam(int onlycheck,int *bck_litidx);
static void dopragma(void); static void dopragma(void);
static void pragma_apply(symbol *sym); static void pragma_apply(symbol *sym);
@ -8284,36 +8285,36 @@ static int *readwhile(void)
} /* if */ } /* 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 tok;
int bck_litidx,bck_packstr; int bck_packstr;
int i;
cell val; cell val;
char *str; char *str;
needtoken('('); assert(bck_litidx!=NULL);
/* The options are specified as strings, e.g. /* back up 'litidx', so we can remove the string from the literal queue later */
* native Func() __pragma("naked", "deprecated - use OtherFunc() instead"); *bck_litidx=litidx;
* In order to process the options, we can reuse the standard string parsing /* force the string to be packed by default, so it would be easier to process it */
* 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; bck_packstr=sc_packstr;
sc_packstr=TRUE; sc_packstr=TRUE;
do { /* read the string parameter */
/* read the option string */
tok=lex(&val,&str); tok=lex(&val,&str);
sc_packstr=bck_packstr;
if (tok!=tSTRING || !pc_ispackedstr) { if (tok!=tSTRING || !pc_ispackedstr) {
/* either not a string, or the user prepended "!" to the option string */ /* either not a string, or the user prepended "!" to the option string */
char tokstr[2]; char tokstr[2];
if (tok==tSTRING) if (tok==tSTRING) {
tok='!'; tok='!';
litidx=*bck_litidx; /* remove the string from the literal queue */
} /* if */
if (tok<tFIRST) { if (tok<tFIRST) {
sprintf(tokstr,"%c",tok); sprintf(tokstr,"%c",tok);
str=tokstr; str=tokstr;
@ -8321,15 +8322,22 @@ static void dopragma(void)
str=sc_tokens[tok-tFIRST]; str=sc_tokens[tok-tFIRST];
} /* if */ } /* if */
error(1,sc_tokens[tSTRING-tFIRST],str); error(1,sc_tokens[tSTRING-tFIRST],str);
goto next; 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 */ } /* if */
assert(litidx>bck_litidx);
/* swap the cell bytes if we're on a Little Endian platform */ /* swap the cell bytes if we're on a Little Endian platform */
#if BYTE_ORDER==LITTLE_ENDIAN #if BYTE_ORDER==LITTLE_ENDIAN
{ /* local */ { /* local */
char *bytes; char *bytes;
i=(int)val; cell i=val;
do { do {
char t; char t;
bytes=(char *)&litq[i++]; bytes=(char *)&litq[i++];
@ -8351,9 +8359,31 @@ static void dopragma(void)
); /* do */ ); /* do */
} /* local */ } /* local */
#endif #endif
return (char*)&litq[val];
}
static void dopragma(void)
{
int bck_litidx;
int i;
cell val;
char *str;
needtoken('(');
/* The options are specified as strings, e.g.
* native Func() __pragma("naked", "deprecated - use OtherFunc() instead");
* In order to process the options, we can reuse the standard string parsing
* mechanism. This way, as a bonus, we'll also be able to use multi-line
* strings and the stringization operator.
*/
do {
/* read the option string */
str=parsestringparam(FALSE,&bck_litidx);
if (str==NULL)
continue;
/* split the option name from parameters */ /* split the option name from parameters */
str=(char*)&litq[val];
for (i=0; str[i]!='\0' && str[i]!=' '; i++) for (i=0; str[i]!='\0' && str[i]!=' '; i++)
/* nothing */; /* nothing */;
if (str[i]!='\0') { if (str[i]!='\0') {
@ -8417,13 +8447,11 @@ unknown_pragma:
error(207); /* unknown #pragma */ error(207); /* unknown #pragma */
} /* if */ } /* if */
next:
/* remove the string from the literal queue */ /* remove the string from the literal queue */
litidx=bck_litidx; litidx=bck_litidx;
} while (matchtoken(',')); } while (matchtoken(','));
needtoken(')'); needtoken(')');
sc_packstr=bck_packstr;
} }
static void pragma_apply(symbol *sym) static void pragma_apply(symbol *sym)