wpp: Add I/O callbacks [try 2]
Matteo Bruni
matteo.mystral at gmail.com
Sun Oct 11 10:07:49 CDT 2009
The same as try 1
[http://www.winehq.org/pipermail/wine-patches/2009-October/079610.html]
but now without the getter/setter functions and with currentfile
variable inside pp_status.
-------------- next part --------------
From d8e602170320f2cdfd5b346e2239d5b69d00cd2c Mon Sep 17 00:00:00 2001
From: Matteo Bruni <matteo.mystral at gmail.com>
Date: Wed, 30 Sep 2009 20:15:38 +0200
Subject: wpp: Add I/O callbacks.
---
include/wine/wpp.h | 17 +++++
libs/wpp/ppl.l | 70 +++++++++++++++++--
libs/wpp/ppy.y | 14 ++--
libs/wpp/preproc.c | 182 ++++++++++++++++++++++++++++--------------------
libs/wpp/wpp.c | 8 +-
libs/wpp/wpp_private.h | 4 +-
6 files changed, 199 insertions(+), 96 deletions(-)
diff --git a/include/wine/wpp.h b/include/wine/wpp.h
index dd341bd..daba277 100644
--- a/include/wine/wpp.h
+++ b/include/wine/wpp.h
@@ -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 );
diff --git a/libs/wpp/ppl.l b/libs/wpp/ppl.l
index 48a6959..05e7af2 100644
--- a/libs/wpp/ppl.l
+++ b/libs/wpp/ppl.l
@@ -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,7 +1385,8 @@ static bufferstackentry_t *pop_buffer(void)
bufferstack[bufferstackidx].filename,
bufferstack[bufferstackidx].should_pop);
- ppy__switch_to_buffer(bufferstack[bufferstackidx].bufferstate);
+ 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");
}
/*
diff --git a/libs/wpp/ppy.y b/libs/wpp/ppy.y
index b525e2f..5a63494 100644
--- a/libs/wpp/ppy.y
+++ b/libs/wpp/ppy.y
@@ -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)
diff --git a/libs/wpp/preproc.c b/libs/wpp/preproc.c
index 874e54c..2eb3133 100644
--- a/libs/wpp/preproc.c
+++ b/libs/wpp/preproc.c
@@ -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,
};
diff --git a/libs/wpp/wpp.c b/libs/wpp/wpp.c
index afca1bb..935bd49 100644
--- a/libs/wpp/wpp.c
+++ b/libs/wpp/wpp.c
@@ -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;
}
diff --git a/libs/wpp/wpp_private.h b/libs/wpp/wpp_private.h
index e082213..d737495 100644
--- a/libs/wpp/wpp_private.h
+++ b/libs/wpp/wpp_private.h
@@ -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, ...);
/*
* From ppy.y
--
1.6.3.3
More information about the wine-patches
mailing list