1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
|
/*
\funcref{directive}{void directive ()}
{}
{}
{error(), pushfile(), insert()}
{lexer()}
{directiv.c}
{
{\em directive()} is called from {\em lexer()} when a `\#' character is
read in the input file. {\em directive()} does not expect to read the
`\#' character. Three directives are recognized:
\begin{itemize}
\item {\bf \#} {\em [spaces]} {\bf include} {\em [spaces]} {\bf
"}{\em filename}{\bf "}. When this directive is read, {\em
pushfile()} is called to start processing the included file.
Analogous to {\bf C}, an {\bf \#include} $<$...$>$ form is
supported.
\item {\bf \#} {\em [spaces]} {\bf define} {\em [spaces]} {\em name}
{\em [spaces]} {\em [redefinition]}. When this directive is read,
{\em insert()} is called to insert the definition in the symbol
table. The defined {\em name} is passed to {\em insert()} as
argument; the redefinition is stored in the lexical buffer {\em
lexbuf}.
\item {\bf \#\!} \ldots
The line containing this directive is skipped. The directive is
intended to be used on {\sc unix} platforms, where it can be used
to execute an icmake script.
\end{itemize}
Other directives following the `\#' character lead to an error.
}
*/
#include "icm-pp.h"
static int isdefd (char *id)
{
register int
i;
if ( (i = finddef (id)) < 0 ||
(!strcmp (defined [i].redef, "0"))
)
return (0);
return (1);
}
void directive ()
{
register int
imdir_used,
index,
ch;
static char
dirsep [2] = { DIRSEP, '\0' },
idname [200];
char
filename [_MAX_PATH];
/* directive is #! */
if ((ch = fgetc (filestack [filesp].f)) == '!')
{ /* skip while not \n and not EOF */
while ((ch = fgetc (filestack [filesp].f)) != '\n' && ch != EOF)
;
ungetc (ch, filestack [filesp].f); /* push back that char */
return; /* all done here */
}
/* not #!, but maybe '# ' */
while (ch == ' ' || ch == '\t') /* skip all blanks */
ch = fgetc (filestack [filesp].f);
ungetc (ch, filestack [filesp].f); /* push back next char, not ' ' */
if (! fscanf (filestack [filesp].f, "%s", lexbuf))
error ("%s: %d: bad preprocessor directive",
filestack [filesp].n, filestack [filesp].l);
if (! strncmp (lexbuf, "include", 7))
{
imdir_used = 0; /* assume include "..." form */
while ( (ch = fgetc (filestack [filesp].f)) == ' ' ||
ch == '\t'
)
;
if (ch != '\"' && ch != '<')
error ("%s: %d: \" or < expected after #include directive",
filestack [filesp].n, filestack [filesp].l);
if (ch == '<') /* include <...> form? */
imdir_used++;
index = 0;
while ( (ch = fgetc (filestack [filesp].f)) != '\"' && ch != '>')
if (ch == '\n' || ch == EOF)
error ("%s: %d: unterminated name after #include directive",
filestack [filesp].n, filestack [filesp].l);
else
lexbuf [index++] = (char) ch;
lexbuf [index] = '\0';
while ( (ch = fgetc (filestack [filesp].f)) != '\n' &&
ch != EOF)
;
ungetc (ch, filestack [filesp].f);
if (output_active)
{
if (imdir_used)
{
strcpy (filename, imdir);
strcat (filename, dirsep);
strcat (filename, lexbuf);
pushfile (filename);
}
else
pushfile (lexbuf);
}
}
else if (! strncmp (lexbuf, "define", 6))
{
while /* define read, skip blanks */
(
(ch = fgetc (filestack [filesp].f)) == ' '
||
ch == '\t'
)
;
ungetc (ch, filestack [filesp].f); /* push back first non-blank */
getident (idname); /* get the name of the define */
while /* skip blanks again */
(
(ch = fgetc (filestack [filesp].f)) == ' '
||
ch == '\t'
)
;
ungetc (ch, filestack [filesp].f); /* and push-back non-blank */
index = 0; /* read the line-remainder */
while
(
(ch = fgetc (filestack [filesp].f)) != '\n'
&&
ch != EOF
)
lexbuf [index++] = (char) ch;
lexbuf [index] = '\0'; /* terminate the line */
no_comment(); /* remove comment from lexbuf */
ungetc (ch, filestack [filesp].f);
if (output_active)
insert (idname);
}
else if (! strncmp (lexbuf, "ifndef", 6))
{
/* skip blanks */
while ( (ch = fgetc (filestack [filesp].f)) == ' ' || ch == '\t')
;
ungetc (ch, filestack [filesp].f); /* push back first non-blank */
getident (idname); /* get the name of the define */
/* terminate the line */
while ( (ch = fgetc (filestack [filesp].f)) != '\n' )
if (ch == EOF)
error ("%s: #ifndef at end-of-file",
filestack [filesp].n);
ungetc (ch, filestack [filesp].f); /* and push-back non-blank */
output_active = ! isdefd (idname);
}
else if (! strncmp (lexbuf, "ifdef", 5))
{
/* skip blanks */
while ( (ch = fgetc (filestack [filesp].f)) == ' ' || ch == '\t')
;
ungetc (ch, filestack [filesp].f); /* push back first non-blank */
getident (idname); /* get the name of the define */
/* terminate the line */
while ( (ch = fgetc (filestack [filesp].f)) != '\n' )
if (ch == EOF)
error ("%s: #ifdef at end-of-file",
filestack [filesp].n);
ungetc (ch, filestack [filesp].f); /* and push-back non-blank */
output_active = isdefd (idname);
}
else if (! strncmp (lexbuf, "else", 4))
{
/* terminate the line */
while ( (ch = fgetc (filestack [filesp].f)) != '\n' )
if (ch == EOF)
error ("%s: #else at end-of-file",
filestack [filesp].n);
ungetc (ch, filestack [filesp].f); /* and push-back non-blank */
output_active = !output_active;
}
else if (! strncmp (lexbuf, "endif", 5))
{
/* terminate the line */
while ( (ch = fgetc (filestack [filesp].f)) != '\n' )
if (ch == EOF)
error ("%s: #ifdef at end-of-file",
filestack [filesp].n);
ungetc (ch, filestack [filesp].f); /* and push-back non-blank */
output_active = 1;
}
else
error ("%s: %d: bad preprocessor directive",
filestack [filesp].n, filestack [filesp].l);
}
|