wpp: Add I/O callbacks.
This commit is contained in:
parent
17c1881953
commit
e773c516ba
|
@ -26,6 +26,23 @@
|
|||
|
||||
struct wpp_callbacks
|
||||
{
|
||||
/* I/O callbacks */
|
||||
|
||||
/* Looks for a file to include, returning the path where it is found */
|
||||
/* parent_name is the directory of the parent source file (for local
|
||||
* includes), includepath is an array of additional include paths */
|
||||
char *(*lookup)( const char *filename, const char *parent_name,
|
||||
char **include_path, int include_path_count );
|
||||
/* Opens an include file */
|
||||
/* The type param is true if it is a local ("...") include */
|
||||
void *(*open)( const char *filename, int type );
|
||||
/* Closes a previously opened file */
|
||||
void (*close)( void *file );
|
||||
/* Reads buffer from the input */
|
||||
int (*read)( void *file, char *buffer, unsigned int len );
|
||||
/* Writes buffer to the output */
|
||||
void (*write)( const char *buffer, unsigned int len );
|
||||
|
||||
/* Error callbacks */
|
||||
void (*error)( const char *file, int line, int col, const char *near, const char *msg, va_list ap );
|
||||
void (*warning)( const char *file, int line, int col, const char *near, const char *msg, va_list ap );
|
||||
|
|
|
@ -178,6 +178,7 @@ ul [uUlL]|[uUlL][lL]|[lL][uU]|[lL][lL][uU]|[uU][lL][lL]|[lL][uU][lL]
|
|||
#define YY_NO_UNISTD_H
|
||||
#endif
|
||||
|
||||
#include "wine/wpp.h"
|
||||
#include "wpp_private.h"
|
||||
#include "ppy.tab.h"
|
||||
|
||||
|
@ -205,6 +206,7 @@ ul [uUlL]|[uUlL][lL]|[lL][uU]|[lL][lL][uU]|[uU][lL][lL]|[lL][uU][lL]
|
|||
|
||||
typedef struct bufferstackentry {
|
||||
YY_BUFFER_STATE bufferstate; /* Buffer to switch back to */
|
||||
void *filehandle; /* Handle to be used with wpp_callbacks->read */
|
||||
pp_entry_t *define; /* Points to expanding define or NULL if handling includes */
|
||||
int line_number; /* Line that we were handling */
|
||||
int char_number; /* The current position on that line */
|
||||
|
@ -298,6 +300,56 @@ include_state_t pp_incl_state =
|
|||
|
||||
includelogicentry_t *pp_includelogiclist = NULL;
|
||||
|
||||
#define YY_INPUT(buf,result,max_size) \
|
||||
{ \
|
||||
result = wpp_callbacks->read(pp_status.file, buf, max_size); \
|
||||
}
|
||||
|
||||
#define BUFFERINITIALCAPACITY 256
|
||||
|
||||
void pp_writestring(const char *format, ...)
|
||||
{
|
||||
va_list valist;
|
||||
int len;
|
||||
static char *buffer;
|
||||
static int buffercapacity;
|
||||
char *new_buffer;
|
||||
|
||||
if(buffercapacity == 0)
|
||||
{
|
||||
buffer = pp_xmalloc(BUFFERINITIALCAPACITY);
|
||||
if(buffer == NULL)
|
||||
return;
|
||||
buffercapacity = BUFFERINITIALCAPACITY;
|
||||
}
|
||||
|
||||
va_start(valist, format);
|
||||
len = vsnprintf(buffer, buffercapacity,
|
||||
format, valist);
|
||||
/* If the string is longer than buffersize, vsnprintf returns
|
||||
* the string length with glibc >= 2.1, -1 with glibc < 2.1 */
|
||||
while(len > buffercapacity || len < 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
buffercapacity *= 2;
|
||||
} while(len > buffercapacity);
|
||||
|
||||
new_buffer = pp_xrealloc(buffer, buffercapacity);
|
||||
if(new_buffer == NULL)
|
||||
{
|
||||
va_end(valist);
|
||||
return;
|
||||
}
|
||||
buffer = new_buffer;
|
||||
len = vsnprintf(buffer, buffercapacity,
|
||||
format, valist);
|
||||
}
|
||||
va_end(valist);
|
||||
|
||||
wpp_callbacks->write(buffer, len);
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
/*
|
||||
|
@ -1243,6 +1295,7 @@ static void push_buffer(pp_entry_t *ppp, char *filename, char *incname, int pop)
|
|||
|
||||
memset(&bufferstack[bufferstackidx], 0, sizeof(bufferstack[0]));
|
||||
bufferstack[bufferstackidx].bufferstate = YY_CURRENT_BUFFER;
|
||||
bufferstack[bufferstackidx].filehandle = pp_status.file;
|
||||
bufferstack[bufferstackidx].define = ppp;
|
||||
bufferstack[bufferstackidx].line_number = pp_status.line_number;
|
||||
bufferstack[bufferstackidx].char_number = pp_status.char_number;
|
||||
|
@ -1284,8 +1337,8 @@ static bufferstackentry_t *pop_buffer(void)
|
|||
{
|
||||
if(!bufferstack[bufferstackidx].should_pop)
|
||||
{
|
||||
fclose(ppy_in);
|
||||
fprintf(ppy_out, "# %d \"%s\" 2\n", bufferstack[bufferstackidx].line_number, bufferstack[bufferstackidx].filename);
|
||||
wpp_callbacks->close(pp_status.file);
|
||||
pp_writestring("# %d \"%s\" 2\n", bufferstack[bufferstackidx].line_number, bufferstack[bufferstackidx].filename);
|
||||
|
||||
/* We have EOF, check the include logic */
|
||||
if(pp_incl_state.state == 2 && !pp_incl_state.seen_junk && pp_incl_state.ppp)
|
||||
|
@ -1332,6 +1385,7 @@ static bufferstackentry_t *pop_buffer(void)
|
|||
bufferstack[bufferstackidx].filename,
|
||||
bufferstack[bufferstackidx].should_pop);
|
||||
|
||||
pp_status.file = bufferstack[bufferstackidx].filehandle;
|
||||
ppy__switch_to_buffer(bufferstack[bufferstackidx].bufferstate);
|
||||
|
||||
if(bufferstack[bufferstackidx].should_pop)
|
||||
|
@ -1499,7 +1553,7 @@ static void put_buffer(const char *s, int len)
|
|||
if(top_macro())
|
||||
add_text_to_macro(s, len);
|
||||
else
|
||||
fwrite(s, 1, len, ppy_out);
|
||||
wpp_callbacks->write(s, len);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1513,6 +1567,7 @@ void pp_do_include(char *fname, int type)
|
|||
char *newpath;
|
||||
int n;
|
||||
includelogicentry_t *iep;
|
||||
void *fp;
|
||||
|
||||
if(!fname)
|
||||
return;
|
||||
|
@ -1541,7 +1596,7 @@ void pp_do_include(char *fname, int type)
|
|||
/* Undo the effect of the quotation */
|
||||
fname[n-1] = '\0';
|
||||
|
||||
if((ppy_in = pp_open_include(fname+1, type ? pp_status.input : NULL, &newpath)) == NULL)
|
||||
if((fp = pp_open_include(fname+1, type ? pp_status.input : NULL, &newpath)) == NULL)
|
||||
{
|
||||
ppy_error("Unable to open include file %s", fname+1);
|
||||
return;
|
||||
|
@ -1556,9 +1611,10 @@ void pp_do_include(char *fname, int type)
|
|||
if(pp_status.debug)
|
||||
fprintf(stderr, "pp_do_include: %s:%d: include_state=%d, include_ppp='%s', include_ifdepth=%d\n",
|
||||
pp_status.input, pp_status.line_number, pp_incl_state.state, pp_incl_state.ppp, pp_incl_state.ifdepth);
|
||||
ppy__switch_to_buffer(ppy__create_buffer(ppy_in, YY_BUF_SIZE));
|
||||
pp_status.file = fp;
|
||||
ppy__switch_to_buffer(ppy__create_buffer(NULL, YY_BUF_SIZE));
|
||||
|
||||
fprintf(ppy_out, "# 1 \"%s\" 1%s\n", newpath, type ? "" : " 3");
|
||||
pp_writestring("# 1 \"%s\" 1%s\n", newpath, type ? "" : " 3");
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -279,20 +279,20 @@ preprocessor
|
|||
| tMACRO res_arg allmargs tMACROEND opt_mtexts tNL {
|
||||
pp_add_macro($1, macro_args, nmacro_args, $5);
|
||||
}
|
||||
| tLINE tSINT tDQSTRING tNL { if($3) fprintf(ppy_out, "# %d %s\n", $2 , $3); free($3); }
|
||||
| tGCCLINE tSINT tDQSTRING tNL { if($3) fprintf(ppy_out, "# %d %s\n", $2 , $3); free($3); }
|
||||
| tLINE tSINT tDQSTRING tNL { if($3) pp_writestring("# %d %s\n", $2 , $3); free($3); }
|
||||
| tGCCLINE tSINT tDQSTRING tNL { if($3) pp_writestring("# %d %s\n", $2 , $3); free($3); }
|
||||
| tGCCLINE tSINT tDQSTRING tSINT tNL
|
||||
{ if($3) fprintf(ppy_out, "# %d %s %d\n", $2, $3, $4); free($3); }
|
||||
{ if($3) pp_writestring("# %d %s %d\n", $2, $3, $4); free($3); }
|
||||
| tGCCLINE tSINT tDQSTRING tSINT tSINT tNL
|
||||
{ if($3) fprintf(ppy_out, "# %d %s %d %d\n", $2 ,$3, $4, $5); free($3); }
|
||||
{ if($3) pp_writestring("# %d %s %d %d\n", $2 ,$3, $4, $5); free($3); }
|
||||
| tGCCLINE tSINT tDQSTRING tSINT tSINT tSINT tNL
|
||||
{ if($3) fprintf(ppy_out, "# %d %s %d %d %d\n", $2 ,$3 ,$4 ,$5, $6); free($3); }
|
||||
{ if($3) pp_writestring("# %d %s %d %d %d\n", $2 ,$3 ,$4 ,$5, $6); free($3); }
|
||||
| tGCCLINE tSINT tDQSTRING tSINT tSINT tSINT tSINT tNL
|
||||
{ if($3) fprintf(ppy_out, "# %d %s %d %d %d %d\n", $2 ,$3 ,$4 ,$5, $6, $7); free($3); }
|
||||
{ if($3) pp_writestring("# %d %s %d %d %d %d\n", $2 ,$3 ,$4 ,$5, $6, $7); free($3); }
|
||||
| tGCCLINE tNL /* The null-token */
|
||||
| tERROR opt_text tNL { ppy_error("#error directive: '%s'", $2); free($2); }
|
||||
| tWARNING opt_text tNL { ppy_warning("#warning directive: '%s'", $2); free($2); }
|
||||
| tPRAGMA opt_text tNL { fprintf(ppy_out, "#pragma %s\n", $2 ? $2 : ""); free($2); }
|
||||
| tPRAGMA opt_text tNL { pp_writestring("#pragma %s\n", $2 ? $2 : ""); free($2); }
|
||||
| tPPIDENT opt_text tNL { if(pp_status.pedantic) ppy_warning("#ident ignored (arg: '%s')", $2); free($2); }
|
||||
| tRCINCLUDE tRCINCLUDEPATH {
|
||||
if($2)
|
||||
|
|
|
@ -115,6 +115,100 @@ char *pp_xstrdup(const char *str)
|
|||
return memcpy(s, str, len);
|
||||
}
|
||||
|
||||
static char *wpp_default_lookup(const char *name, const char *parent_name,
|
||||
char **include_path, int include_path_count)
|
||||
{
|
||||
char *cpy;
|
||||
char *cptr;
|
||||
char *path;
|
||||
const char *ccptr;
|
||||
int i, fd;
|
||||
|
||||
cpy = pp_xmalloc(strlen(name)+1);
|
||||
if(!cpy)
|
||||
return NULL;
|
||||
cptr = cpy;
|
||||
|
||||
for(ccptr = name; *ccptr; ccptr++)
|
||||
{
|
||||
/* Convert to forward slash */
|
||||
if(*ccptr == '\\') {
|
||||
/* kill double backslash */
|
||||
if(ccptr[1] == '\\')
|
||||
ccptr++;
|
||||
*cptr = '/';
|
||||
}else {
|
||||
*cptr = *ccptr;
|
||||
}
|
||||
cptr++;
|
||||
}
|
||||
*cptr = '\0';
|
||||
|
||||
if(parent_name)
|
||||
{
|
||||
/* Search directory of parent include and then -I path */
|
||||
const char *p;
|
||||
|
||||
if ((p = strrchr( parent_name, '/' ))) p++;
|
||||
else p = parent_name;
|
||||
path = pp_xmalloc( (p - parent_name) + strlen(cpy) + 1 );
|
||||
if(!path)
|
||||
{
|
||||
free(cpy);
|
||||
return NULL;
|
||||
}
|
||||
memcpy( path, parent_name, p - parent_name );
|
||||
strcpy( path + (p - parent_name), cpy );
|
||||
fd = open( path, O_RDONLY );
|
||||
if (fd != -1)
|
||||
{
|
||||
close( fd );
|
||||
free( cpy );
|
||||
return path;
|
||||
}
|
||||
free( path );
|
||||
}
|
||||
/* Search -I path */
|
||||
for(i = 0; i < include_path_count; i++)
|
||||
{
|
||||
path = pp_xmalloc(strlen(include_path[i]) + strlen(cpy) + 2);
|
||||
if(!path)
|
||||
{
|
||||
free(cpy);
|
||||
return NULL;
|
||||
}
|
||||
strcpy(path, include_path[i]);
|
||||
strcat(path, "/");
|
||||
strcat(path, cpy);
|
||||
fd = open( path, O_RDONLY );
|
||||
if (fd != -1)
|
||||
{
|
||||
close( fd );
|
||||
free( cpy );
|
||||
return path;
|
||||
}
|
||||
free( path );
|
||||
}
|
||||
free( cpy );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *wpp_default_open(const char *filename, int type) {
|
||||
return fopen(filename,"rt");
|
||||
}
|
||||
|
||||
static void wpp_default_close(void *file) {
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
static int wpp_default_read(void *file, char *buffer, unsigned int len){
|
||||
return fread(buffer, 1, len, file);
|
||||
}
|
||||
|
||||
static void wpp_default_write( const char *buffer, unsigned int len ) {
|
||||
fwrite(buffer, 1, len, ppy_out);
|
||||
}
|
||||
|
||||
/* Don't comment on the hash, its primitive but functional... */
|
||||
static int pphash(const char *str)
|
||||
{
|
||||
|
@ -403,88 +497,17 @@ int wpp_add_include_path(const char *path)
|
|||
|
||||
char *wpp_find_include(const char *name, const char *parent_name)
|
||||
{
|
||||
char *cpy;
|
||||
char *cptr;
|
||||
char *path;
|
||||
const char *ccptr;
|
||||
int i, fd;
|
||||
|
||||
cpy = pp_xmalloc(strlen(name)+1);
|
||||
if(!cpy)
|
||||
return NULL;
|
||||
cptr = cpy;
|
||||
|
||||
for(ccptr = name; *ccptr; ccptr++)
|
||||
{
|
||||
/* Convert to forward slash */
|
||||
if(*ccptr == '\\') {
|
||||
/* kill double backslash */
|
||||
if(ccptr[1] == '\\')
|
||||
ccptr++;
|
||||
*cptr = '/';
|
||||
}else {
|
||||
*cptr = *ccptr;
|
||||
}
|
||||
cptr++;
|
||||
}
|
||||
*cptr = '\0';
|
||||
|
||||
if(parent_name)
|
||||
{
|
||||
/* Search directory of parent include and then -I path */
|
||||
const char *p;
|
||||
|
||||
if ((p = strrchr( parent_name, '/' ))) p++;
|
||||
else p = parent_name;
|
||||
path = pp_xmalloc( (p - parent_name) + strlen(cpy) + 1 );
|
||||
if(!path)
|
||||
{
|
||||
free(cpy);
|
||||
return NULL;
|
||||
}
|
||||
memcpy( path, parent_name, p - parent_name );
|
||||
strcpy( path + (p - parent_name), cpy );
|
||||
fd = open( path, O_RDONLY );
|
||||
if (fd != -1)
|
||||
{
|
||||
close( fd );
|
||||
free( cpy );
|
||||
return path;
|
||||
}
|
||||
free( path );
|
||||
}
|
||||
/* Search -I path */
|
||||
for(i = 0; i < nincludepath; i++)
|
||||
{
|
||||
path = pp_xmalloc(strlen(includepath[i]) + strlen(cpy) + 2);
|
||||
if(!path)
|
||||
{
|
||||
free(cpy);
|
||||
return NULL;
|
||||
}
|
||||
strcpy(path, includepath[i]);
|
||||
strcat(path, "/");
|
||||
strcat(path, cpy);
|
||||
fd = open( path, O_RDONLY );
|
||||
if (fd != -1)
|
||||
{
|
||||
close( fd );
|
||||
free( cpy );
|
||||
return path;
|
||||
}
|
||||
free( path );
|
||||
}
|
||||
free( cpy );
|
||||
return NULL;
|
||||
return wpp_default_lookup(name, parent_name, includepath, nincludepath);
|
||||
}
|
||||
|
||||
FILE *pp_open_include(const char *name, const char *parent_name, char **newpath)
|
||||
void *pp_open_include(const char *name, const char *parent_name, char **newpath)
|
||||
{
|
||||
char *path;
|
||||
FILE *fp;
|
||||
void *fp;
|
||||
|
||||
if (!(path = wpp_find_include( name, parent_name ))) return NULL;
|
||||
fp = fopen(path, "rt");
|
||||
if (!(path = wpp_callbacks->lookup(name, parent_name, includepath,
|
||||
nincludepath))) return NULL;
|
||||
fp = wpp_callbacks->open(path, parent_name == NULL ? 1 : 0);
|
||||
|
||||
if (fp)
|
||||
{
|
||||
|
@ -687,6 +710,11 @@ static void wpp_default_warning(const char *file, int line, int col, const char
|
|||
|
||||
static const struct wpp_callbacks default_callbacks =
|
||||
{
|
||||
wpp_default_lookup,
|
||||
wpp_default_open,
|
||||
wpp_default_close,
|
||||
wpp_default_read,
|
||||
wpp_default_write,
|
||||
wpp_default_error,
|
||||
wpp_default_warning,
|
||||
};
|
||||
|
|
|
@ -176,8 +176,8 @@ int wpp_parse( const char *input, FILE *output )
|
|||
add_cmdline_defines();
|
||||
add_special_defines();
|
||||
|
||||
if (!input) ppy_in = stdin;
|
||||
else if (!(ppy_in = fopen(input, "rt")))
|
||||
if (!input) pp_status.file = stdin;
|
||||
else if (!(pp_status.file = wpp_callbacks->open(input, 1)))
|
||||
{
|
||||
ppy_error("Could not open %s\n", input);
|
||||
return 2;
|
||||
|
@ -186,13 +186,13 @@ int wpp_parse( const char *input, FILE *output )
|
|||
pp_status.input = input;
|
||||
|
||||
ppy_out = output;
|
||||
fprintf(ppy_out, "# 1 \"%s\" 1\n", input ? input : "");
|
||||
pp_writestring("# 1 \"%s\" 1\n", input ? input : "");
|
||||
|
||||
ret = ppy_parse();
|
||||
/* If there were errors during processing, return an error code */
|
||||
if(!ret && pp_status.state) ret = pp_status.state;
|
||||
|
||||
if (input) fclose(ppy_in);
|
||||
if (input) wpp_callbacks->close(pp_status.file);
|
||||
pp_pop_define_state();
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -207,7 +207,7 @@ void pp_pop_define_state(void);
|
|||
pp_entry_t *pp_add_define(char *def, char *text);
|
||||
pp_entry_t *pp_add_macro(char *ident, marg_t *args[], int nargs, mtext_t *exp);
|
||||
void pp_del_define(const char *name);
|
||||
FILE *pp_open_include(const char *name, const char *parent_name, char **newpath);
|
||||
void *pp_open_include(const char *name, const char *parent_name, char **newpath);
|
||||
void pp_push_if(pp_if_state_t s);
|
||||
void pp_next_if_state(int);
|
||||
pp_if_state_t pp_pop_if(void);
|
||||
|
@ -229,6 +229,7 @@ void pp_internal_error(const char *file, int line, const char *s, ...) __attribu
|
|||
struct pp_status
|
||||
{
|
||||
const char *input; /* current input file name */
|
||||
void *file; /* current input file descriptor */
|
||||
int line_number; /* current line number */
|
||||
int char_number; /* current char number in line */
|
||||
int state; /* current error state */
|
||||
|
@ -253,6 +254,7 @@ void pp_do_include(char *fname, int type);
|
|||
void pp_push_ignore_state(void);
|
||||
void pp_pop_ignore_state(void);
|
||||
|
||||
void pp_writestring(const char *format, ...) __attribute__((format (printf, 1, 2)));
|
||||
|
||||
/*
|
||||
* From ppy.y
|
||||
|
|
Loading…
Reference in New Issue