By default yyout
is set to stdout
and can be redirected to FILE*
stream. Is a way to redirect yyout
to char*
?
There are a number of ways to do it. If you post a bit of your scanner code where you are trying to use yyout may be I can give you a more specific answer:
Typically it's in your action where you'd do this. So instead of using ECHO
or fprintf(yyout...
you'd use something else like
<token> { snprintf(buf, sizeof(buf), "%s", yytext); }
earlier you'd have declared:
char buf[BUFSIZE];
There are clever ways of dealing with the situation, but they are prone to maintenance problems in the long run because they are "clever" .. .and the cleverer a solution the shorter its life. (unless the cleverness is well documented with caveats attached)
int yyprintf(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
if ( some_flag & FLAG_OUTFILE ) {
vfprintf(yyout, fmt, ap);
}
else {
sprintf(buf, fmt, ap);
}
va_end(ap);
}
where buf is a global buffer.
However if you want to make things a bit local:
You want fine grain control over where things go along the way. Sometimes you want output to file, other times to a string, and you don't always know which is which and when and where you can use something like this:
int myvprintf(void *here, size_t len, const char *fmt, va_list ap)
__attribute__((format (gnu_printf, 3, 4), nonnull(1, 3))) {
int rv;
if ( len > 0 ) {
rv = vsnprintf((char *), len, fmt, ap);
}
else {
rv = vfprintf((FILE *)here, fmt, ap);
}
return rv;
}
int myprintf(void *here, size_t len, const char *fmt, ... )
__attribute__((format (gnu_printf, 3, 4), nonnull(1, 3))) {
int rv;
va_list ap;
va_start(ap, fmt);
rv = myvprintf(here, len, fmt, ap);
va_end(ap);
return rv;
}
and use myprintf along the way, you will have control over what is here
all the time.
Don't try this at home. But all yy* identifiers and ECHO are not plain variables, they are #define's. So you could do some clever macro rewriting:
For example, if you are using ECHO everywhere then you can redefine it to do whatever you like (just #undef and #define) in the top section:
%{
#undef ECHO
#define ECHO snprintf(buf, sizeof(buf), "%s", yytext)
%}
%%
<token> ECHO;
%%
just hide it all in convoluted headers and do other cleverness that will make debugging a hell later for a programmer you hate. This can have its own rewards and giggles.