/************************************************************************/
/* */
/* File: pp6.c */
/* */
/* Pragma directives. */
/* */
/* Written by: */
/* Gary Oliver */
/* 3420 NW Elmwood Dr. */
/* PO Box 826 */
/* Corvallis, Oregon 97339 */
/* (503)758-5549 */
/* Maintained by: */
/* Kirk Bailey */
/* Logical Systems */
/* P.O. Box 1702 */
/* Corvallis, OR 97339 */
/* (503)753-9051 */
/* */
/* This program is hereby placed in the public domain. In */
/* contrast to other claims of "public domain", this means no */
/* copyright is claimed and you may do anything you like with PP, */
/* including selling it! As a gesture of courtesy, please retain */
/* the authorship information in the source code and */
/* documentation. */
/* */
/* Functions contained within this module: */
/* */
/* doasm Process #asm/#endasm directives. */
/* dopragma Main #pragma directive processing. */
/* pragasm Process #pragma asm/endasm directives. */
/* pragerror Process #pragma error directive. */
/* pragmsg Process #pragma message directive. */
/* pragopt Process #pragma directives. */
/* pragvalue Process #pragma value directive. */
/* */
/************************************************************************/
#include "pp.h"
#include "ppext.h"
#if (TARGET == T_QC) OR (TARGET == T_QCX) OR (TARGET == T_TCX)
/************************************************************************/
/* */
/* doasm */
/* */
/* Copy "#asm" or "#endasm" to the output. This is basically a */
/* function to clean up for the "#asm"/"#endasm" previously pushed */
/* by the "pragasm" function. */
/* */
/************************************************************************/
void
doasm(asmtype)
int asmtype;/* True if #asm; False if #endasm */
{
puttoken(asmtype ? "#asm" : "#endasm");
}
#endif /* (TARGET == T_QC) OR (TARGET == T_QCX) OR (TARGET == T_TCX) */
/************************************************************************/
/* */
/* dopragma */
/* */
/* Execute the #pragma directive. */
/* */
/* Any unrecognized #pragma lines are passed on to the output file */
/* unless in the FALSE clause of an #if (or equivalent). */
/* */
/************************************************************************/
void
dopragma()
{
int ltr_flag;
int no_flag;
struct ppdir *pp;
char pragbuf[PRAGBUFSIZE];
no_flag = FALSE; /* "no" not encountered */
if((ltr_flag = (getnstoken(GT_STR) == LETTER)) != 0)
{
if(strcmp(Token,"no") == EQUAL)
{
no_flag = TRUE;
ltr_flag = (getnstoken(GT_STR) == LETTER);
}
if(ltr_flag && ((pp = predef(Token,pragtab)) != NULL))
{
/* If unconditionally do it or if emitting code */
if(pp->pp_ifif || (Ifstate == IFTRUE))
{
(void) (*(pp->pp_func))(pp->pp_arg,no_flag,
pp->pp_name);
}
return;
}
}
/*
* We do not understand: print original (or similar) #pragma to output
* if we are emitting code.
*/
if(Ifstate == IFTRUE)
{
puttoken("#pragma "); /* Write #pragma directive */
if(no_flag)
puttoken("no ");
puttoken(Token); /* Unrecognized token */
puttoken(" "); /* Whitespace separating */
/*
* Expand macros...
*/
puttoken(readline(pragbuf,PRAGBUFSIZE,GT_STR));
}
}
#if (TARGET == T_QC) OR (TARGET == T_QCX) OR (TARGET == T_TCX)
/************************************************************************/
/* */
/* pragasm */
/* */
/* Copy code verbatum to output file until a line beginning with */
/* the token "#pragma endasm" is read. */
/* */
/************************************************************************/
void
pragasm(asmtype)
int asmtype;/* True if #asm; False if #endasm */
{
if(Do_asm == asmtype)
{
if(Do_asm)
non_fatal("Already within \"#pragma asm\"","");
else
non_fatal("Not within \"#pragma asm\"","");
}
else
{
pbstr(Do_asm ? "#endasm" : "#asm"); /* For 2nd pass */
pushback('\n'); /* So scaneol finds the end */
Do_asm = asmtype; /* Set flag and let main line handle */
Macexpand = asmtype ? Asmexpand : TRUE; /* Set expand mode */
}
}
#endif /* (TARGET == T_QC) OR (TARGET == T_QCX) OR (TARGET == T_TCX) */
/************************************************************************/
/* */
/* pragendm */
/* */
/* Process "#pragma endmacro" statement as error outside macro */
/* */
/************************************************************************/
void
pragendm()
{
non_fatal("\"#pragma endmacro\" illegal outside macro","");
}
/************************************************************************/
/* */
/* pragerror */
/* */
/* Process "#pragma error" statement. */
/* */
/************************************************************************/
void
pragerror()
{
char msgbuf[MESSAGEBUFSIZE];
non_fatal(readline(msgbuf,MESSAGEBUFSIZE,GT_STR),"");
}
/************************************************************************/
/* */
/* pragmsg */
/* */
/* Process "#pragma message" statement. */
/* */
/* Note: If the file stack is < 0, then all files have been */
/* popped off the stack. Use 0 (the original file name.) */
/* */
/************************************************************************/
void
pragmsg()
{
char msgbuf[MESSAGEBUFSIZE];
printf("<%s> @ %u: MESSAGE: %s\n",
Filestack[Filelevel >= 0 ? Filelevel : 0]->f_name,LLine,
readline(msgbuf,MESSAGEBUFSIZE,GT_STR));
}
/************************************************************************/
/* */
/* pragopt */
/* */
/* Process "#pragma [no] " statements. */
/* */
/************************************************************************/
#ifdef __TURBOC__
#pragma warn -par
#endif /* __TURBOC__ */
void
pragopt(dummy,no_flag,name)
int dummy; /* Placeholder */
int no_flag; /* TRUE if "no" condition */
char *name; /* Name of pragma */
{
char buf[TOKENSIZE + 1];
struct symtab *sym;
char *toptr;
if(strcmp(name,"arg_string") == EQUAL)
A_astring = !no_flag;
#if (TARGET == T_QC) OR (TARGET == T_QCX) OR (TARGET == T_TCX)
else if(strcmp(name,"asm_expand") == EQUAL)
Asmexpand = !no_flag;
#endif /* (TARGET == T_QC) OR (TARGET == T_QCX) OR (TARGET == T_TCX) */
else if(strcmp(name,"comment_recurse") == EQUAL)
A_crecurse = !no_flag;
else if(strcmp(name,"eol_comment") == EQUAL)
A_eolcomment = !no_flag;
else if(strcmp(name,"macro_rescan") == EQUAL)
A_rescan = !no_flag;
else if(strcmp(name,"macro_stack") == EQUAL)
A_stack = !no_flag;
else if(strcmp(name,"trigraph") == EQUAL)
A_trigraph = !no_flag;
/*
* We need to keep track of the current setting of the options via
* the appropriate "____" macro. First we
* synthesize the macro name.
*/
strcpy(buf,"__");
for(toptr = &buf[2]; *name; name++)
*toptr++ = (islower(*name) ? toupper(*name) : *name);
*toptr = '\0';
strcat(buf,"__");
/*
* Now see if it still exists and if its value hasn't been altered
* beyond use by the user doing a undef/define sequence on it.
*/
if((sym = lookup(buf,NULL)) != NULL)
{
if((sym->s_body != NULL) &&
((strcmp(sym->s_body,"0") == EQUAL) ||
(strcmp(sym->s_body,"1") == EQUAL)))
{
if(! no_flag)
*(sym->s_body) = '1';
else
*(sym->s_body) = '0';
}
}
}
#ifdef __TURBOC__
#pragma warn .par
#endif /* __TURBOC__ */
/************************************************************************/
/* */
/* pragvalue */
/* */
/* Process "#pragma value" statement. */
/* */
/************************************************************************/
void
pragvalue()
{
char buf[TOKENSIZE + 1];
sprintf(buf,"%ld",(long) eval());
pbstr(buf); /* Push back into "input" stream */
pushback('\n'); /* So scaneol finds the end */
}